class Method is Routine { }

一种方法类型,其行为方式与 Routine 相同,但有一些例外情况,如下所列。有关方法参数列表的详细信息,请参见 Signature

要在 类定义 外部创建方法,请使用声明符 mymethod。如果提供了 标识符,则方法名称将注入到声明符指定的范围内。

my $m = method ($invocant: $param{
    say "$invocant: '$param'";
}
"greeting".$m("hello");  # OUTPUT: «greeting: 'hello'␤» 
 
<a b c>.&(my method (List:D:{ say self.rakuself }).say;
# OUTPUT: «("a", "b", "c")␤(a b c)␤»

方法的调用者默认为 self。可以使用包括类型笑脸的类型约束,并且对于在类中定义的方法和自由浮动方法,都会遵守该约束。使用 .& 在对象上调用后者。

my method m(Int:D: $b){
    say self.^name
}
my $i = 1;
$i.&m(<a>);
# OUTPUT: «Int␤»

请注意,在类内和类外定义的方法之间的主要区别在于,在后者情况下需要使用 `&` 来调用它们。如果在定义中使用了任何其他 sigil,如第一个示例所示,则也可以使用该 sigil。

方法会自动将额外的命名参数捕获到特殊变量 %_ 中,而其他类型的 Routine 将在运行时抛出异常。因此

method x() {}

实际上等效于

method x(*%_{}

额外的参数将由 nextsame 及其类似项 转发。

class A {
    multi method m(:$a:$b{ say "2 named" }
}
 
class B is A {
    method m(:$a{ say "1 named"nextsame }
}
B.m:1a, :2b );
# OUTPUT: «1 named␤2 named␤»

类型图§

Method 的类型关系
raku-type-graph Method Method Routine Routine Method->Routine Mu Mu Any Any Any->Mu Callable Callable Code Code Code->Any Code->Callable Block Block Block->Code Routine->Block Regex Regex Regex->Method

展开上面的图表