在函数中§
请参阅主要文档 上下文中的proto
proto
是一种正式声明multi
候选者之间共性的方法。它充当一个包装器,可以验证参数,但不能修改参数。考虑这个基本示例
proto congratulate(Str , Str , |)multi congratulate(, )multi congratulate(, , Int )congratulate('being a cool number', 'Fred'); # OKcongratulate('being a cool number', 'Fred', 42); # OK
congratulate('being a cool number', 42); # Proto match error
proto 坚持所有multi congratulate
子例程都符合两个字符串的基本签名,后面可以跟其他参数。|
是一个未命名的 Capture
参数,允许multi
接受其他参数。前两个调用成功,但第三个调用失败(在编译时),因为42
不匹配 Str
。
say .signature # OUTPUT: «(Str $reason, Str $name, | is raw)»
你可以给proto
一个函数体,并将{*}
(注意大括号内没有空格)放在你希望执行分派的地方。当你的例程中有一个“洞”时,这会很有用,它会根据给定的参数给出不同的行为
# attempts to notify someone -- False if unsuccessfulproto notify(Str , Str )
由于proto
是multi
候选者的包装器,例程的multi
候选者的签名不一定必须与proto
的签名匹配;multi
候选者的参数可以是proto
的子类型,multi
候选者的返回类型可以与proto
的返回类型完全不同。在给proto
一个函数体时,使用这种不同的类型特别有用
<LOG WARNING ERROR>;proto debug(DebugType , Str --> Bool)multi debug(LOG;; Str --> 32)multi debug(WARNING;; Str --> 33)multi debug(ERROR;; Str --> 31)
{*}
总是分派给它被调用的参数的候选者。参数默认值和类型强制转换将起作用,但不会传递。
proto mistake-proto(Str() , Int = 42)multi mistake-proto(, )mistake-proto(7, 42); # OUTPUT: «Int» -- not passed on
mistake-proto('test'); # fails -- not passed on
一个使用proto
进行方法的较长的示例展示了如何将公共功能提取到一个 proto 方法中。
my NewClass .= new;.handle('hello world');.handle(<hello world>);.debug = True;.handle('hello world');.handle(<hello world>);.handle('Claire', 'John');# OUTPUT:# in string# in positional# before value is 「hello」# in string# after value is 「hello world」# before value is 「hello world」# in positional# after value is 「hello」# before value is 「hello」# with more than one value# after value is 「Claire is looking askance at John」