我正在浏览例程中的Perl 6文档shift并看到了这个片段:
定义为:
Run Code Online (Sandbox Code Playgroud)multi sub shift(Array:D ) multi method shift(Array:D:)
我知道:D指的Array就是defined不Any和Nil,但有什么:D:?搜索起来非常困难.
类型签名文档的这一部分包含更多语法示例,但没有(据我所知)解释它.
克里斯托夫的回答已经很出色了。我的回答是尝试通过一个具体的小例子来提供一些背景信息。
\n正如 Christoph 所说,在 Raku 中,方法的调用者作为隐式的第一个位置参数传递,然后该参数可用于方法的主体,如下所示self:
class Person {\n has $.name;\n \n method greet( Person $B, $greeting = \'Hello\' ) {\n self.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n }\n}\n\nmy $john = Person.new(name => \'John\');\nmy $dana = Person.new(name => \'Dana\');\nsay $john.greet($dana, \'Good morning\'); # \xc2\xabJohn: Good morning, Dana.\xc2\xbb\nRun Code Online (Sandbox Code Playgroud)\n如果您希望将其绑定到其他内容,请使用您在方法中声明的常规参数(位置参数和命名参数)的method meth-name( invocant : param1, param2, ..., param3) { ... } 语法。param1, param2, ..., param3正如 Christoph 所说,这种语法“即使在[无参数签名]的情况下也是必要的,因此它可以与具有常规位置参数的签名消除歧义。” 所以:
# Person A greets person B.\nmethod greet( $A : Person $B, $greeting = \'Hello\' ) {\n $A.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n您可以更进一步,输入调用者,不一定是因为需要它,而是因为它使方法的签名更具描述性:
\n# Person A greets person B.\nmethod greet( Person $A : Person $B, $greeting = \'Hello\' ) {\n $A.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n如果您不希望该方法greet接受类型对象(例如,Person),而只接受该类型的对象实例(例如,Person.new),那么您可以使用类型\nsmily :D。因此:
# Person A greets person B.\nmethod greet( Person:D $A : Person $B, $greeting = \'Hello\' ) {\n $A.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n类型表情符号是:D(对于DEFINED )、:U(对于未定义) 和(这是不使用或 的:_类型的隐式表情符号)。:D:U
self如果您从方法的签名中删除显式调用者(并恢复为 using ),那么您最终会得到与问题中类似的内容。在这里我只是使用一些空白来让它看起来不那么令人畏惧:
method greet( Person:D : Person $B, $greeting = \'Hello\' ) {\n self.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n附录:
\n在 Raku 中,方法可以限制为仅在类的对象实例上调用(对于对象方法)或仅在类本身上调用(对于类方法);您只需将:D笑脸添加到对象方法的类名称中,并将:U笑脸添加到类方法的类名称中:
method object-method( CLASSNAME:D : ) { ... }\nmethod class-method( CLASSNAME:U : ) { ... }\nRun Code Online (Sandbox Code Playgroud)\n但是,这并不像可能的那样通用,您可以使用编译时变量::?CLASS来确定当前类,从而无需将类名称放在那里。例如,限制greet仅在以下实例对象上调用Person:
method greet( ::?CLASS:D: Person $B, $greeting = \'Hello\' ) {\n self.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n与往常一样,如果您对冒号感到困惑,您总是可以在类型 smily 所附加的任何内容和其余内容之间放置一些空格,:以使内容更加明显,如下所示:
method greet( ::?CLASS:D : Person $B, $greeting = \'Hello\' ) {\n self.name ~ ": $greeting, " ~ $B.name ~ \'.\'\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
344 次 |
| 最近记录: |