我正在浏览Perl 6 docs on the shift
routine并看到了这个片段:
定义为:
multi sub shift(Array:D ) multi method shift(Array:D:)
我知道:D
表示Array
是defined
而不是Any
或Nil
,但:D:
是什么?它很难搜索。
This section包含更多语法示例,但不(据我所知)解释它。
答案 0 :(得分:13)
方法的调用作为隐式的第一个参数传递。如果您想在签名中使用显式参数(例如,添加类型为:D
的笑脸,或者只是为了给它提供更具描述性的名称),则需要将其与:
分开,而不是来自参数列表其余部分的,
。即使在列表为空的情况下也是如此,因此可以从具有常规位置参数的签名中消除歧义。
可以找到更多信息in the design documents。
答案 1 :(得分:4)
Christoph的答案已经很好。我的答案是尝试通过一个小的具体示例提供一些背景信息。
如克里斯托弗(Christoph)所述,在Raku中,方法的调用者作为隐式的第一个位置参数传递,然后以self
的形式供该方法的主体使用:
class Person {
has $.name;
method greet( Person $B, $greeting = 'Hello' ) {
$A.name ~ ": $greeting, " ~ $B.name ~ '.'
}
}
my $john = Person.new(name => 'John');
my $dana = Person.new(name => 'Dana');
say $john.greet($dana, 'Good morning'); # «John: Good morning, Dana.»
如果希望将其绑定到其他对象,请使用语法method meth-name( invocant : param1, param2, ..., param3) { ... }
,其中param1, param2, ..., param3
是您在方法中声明的常规参数(位置参数和命名参数)。正如克里斯托夫(Christoph)所言,这种语法“即使在[无Parparmer签名]的情况下也是必要的,因此可以将其与带有常规位置参数的签名区分开。”因此:
# Person A greets person B.
method greet( $A : Person $B, $greeting = 'Hello' ) {
self.name ~ ": $greeting, " ~ $B.name ~ '.'
}
您可以走得更远,也可以键入请求者,这不一定是因为需要它,而是因为它使方法的签名更具描述性:
# Person A greets person B.
method greet( Person $A : Person $B, $greeting = 'Hello' ) {
$A.name ~ ": $greeting, " ~ $B.name ~ '.'
}
如果您不希望方法greet
接受类型对象(例如Person
),而只接受类型(例如Person.new
)的对象实例,则可以利用类型
笑着 :D
。因此:
# Person A greets person B.
method greet( Person:D $A : Person $B, $greeting = 'Hello' ) {
$A.name ~ ": $greeting, " ~ $B.name ~ '.'
}
type smilies为:D
(对于 D 定义),:U
(对于 U 未定义)和{{1 }}(这是既不使用:_
也不使用:D
的类型的隐含笑容)。
如果从方法的签名中删除显式调用者(并恢复为使用:U
),则最终将得到与问题类似的内容。在这里,我只是使用一些空格使它看起来不那么令人生畏:
self
附录:
在Raku中,可以将方法限制为只能在类的对象实例上(对于 object方法)或仅在类本身上(对于 class方法)被调用。 ;您只需将method greet( Person:D : Person $B, $greeting = 'Hello' ) {
self.name ~ ": $greeting, " ~ $B.name ~ '.'
}
smily添加到对象方法的类名中,并将:D
smily添加到类方法的类名中
:U
但是,这并不像一般的那么普遍,您可以使用编译时变量::?CLASS
来确定当前类,从而消除了将类名放在此处的需要。例如,限制method object-method( CLASSNAME:D : ) { ... }
method class-method( CLASSNAME:U : ) { ... }
仅在greet
的实例对象上调用:
Person
就像总是被冒号弄糊涂一样,您总是可以在smily所附加的任何东西和其余的method greet( ::?CLASS:D: Person $B, $greeting = 'Hello' ) {
self.name ~ ": $greeting, " ~ $B.name ~ '.'
}
之间放置一些空格,以使情况更加明显,例如:
: