@jjmerelo 的回答涵盖了基础知识。这个补充性的答案旨在较为详尽,但希望不会详尽无遗,涵盖了陷阱、罕见案例和建议。
foo: valuea, valueb, ...
也许令人惊讶的是,这就是not调用子函数或方法foo
.
相反,它是一个以label, foo:
.
The say:
您的问题中的行在普通程序中不起作用:
say: <a b c>; # Useless use of constant value a b c ...
“无用的使用”警告是指<a b c>
没有以有用的方式使用。这say:
不对值列表执行任何操作。它只是一个标签,没有任何作用。
想必您正在使用类似 Perl 6 REPL 的东西。 REPL 自动say
s 行中的最后一个值(如果未以其他方式使用),从而使该行看起来可以正常工作而不会发出警告。
.a-method:
If a 后缀方法调用使用表格.a-method除了调用者(调用者左边的参数)之外没有任何参数.
, or 当前主题如果没有明确的调用者)那么你可以将其写成以下形式:
42.say ;
您可以选择附加一个冒号:
42.say: ;
没有充分的理由,但它符合:
.a-method: arg2, arg3, ...
如果您想向后缀提供一个或多个参数(调用者除外).a-method
打电话,那么你必须选择两种方式之一来介绍他们。
One way is to write a colon immediately after the method name, before the argument(s). There must be no space between the method name and colon, and there must be space after the colon before the method argument(s).1
例如,以下在前面使用冒号Numeric
以下方法调用中的参数:
say <abc 2 def ghi> .first: Numeric ; # 2
在上面的行中,方法调用表达式 (.first: Numeric
) 以语句终止符 (;
)。如果存在封闭子表达式(例如数组下标),则方法调用表达式将在该子表达式的末尾结束:
say .[1 + .first: Numeric] given <abc 2 def ghi> ; # ghi
冒号形式方法调用的参数列表也由有效的语句修饰符 like given
:
say .first: Numeric given <abc 2 def ghi> ; # 2
a-sub arg1, arg2, ...
这是子程序调用的相应形式。唯一的格式差异是子程序没有调用者或.
在子名和您之前必须省略子名称后面的冒号。
.a-method( arg2, arg3, ... )
a-sub( arg1, arg2, ... )
用于方法和子调用的另一种常见形式是在方法或子名称后立即用括号来分隔参数。左括号必须立即遵循,例程名称和之间没有任何空格(
.
这是与以下一起使用的括号.first
method:
say 1 + .first(Numeric) given <abc 2 def ghi> ; # 3
这样做的优点是它可以说比使用外括号的替代方案更漂亮:
say 1 + (.first: Numeric) given <abc 2 def ghi> ; # 3
如果要将子调用直接放在双引号字符串内,则需要在子名称前添加前缀&
sigil 并使用后缀括号形式:
my @array = <abc 2 def ghi> ;
say "first number is &first(Numeric,@array)" ; # first number is 2
要放入方法调用,您必须再次使用后缀括号形式,并且还必须提供显式调用者(您不能只写"Some text .a-method()"
):
my @array = <abc 2 def ghi> ;
say "first number is @array.first(Numeric)" ; # first number is 2
如果没有参数(除了方法调用的调用者之外),如果您想在字符串中插入子或方法调用,您仍然需要使用带有空括号的这种形式:
my @array = <abc 2 def ghi> ;
say "no method call @array[3].uc" ; # no method call ghi.uc
say "with method call @array[3].uc()" ; # with method call GHI
say "&rand"; # &rand
say "&rand()"; # 0.929123203371282
.a-method ( arrgh, arrgh, ... ) ;
这行不通。
因为.a-method
后面没有冒号,则方法调用被视为完成。
这意味着下一个事物必须是表达式/语句结束者,例如;
,或将对方法调用的结果进行操作的后缀运算符,或对结果和某些后续参数进行操作的中缀运算符。
But ( arrgh, arrgh, ... )
这些都不是。因此,您会收到“连续两项”编译错误。
.a-method:( arrgh, arrgh, ... ) ;
.a-method: ( arrgh, arrgh, ... ) ;
一般来说,请勿混合使用:
在参数周围使用括号作为方法调用的一部分。这样做没有充分的理由,因为它要么不起作用,要么只是偶然起作用,要么起作用但很可能会让读者感到困惑。
如果冒号和左括号之间没有空格,则会产生一个神秘的编译错误:
This type (QAST::WVal) does not support positional operations
留出空间似乎可行——但通常只能靠运气:
say .first: (Numeric) given <abc 2 def ghi> ; # 2
The (Numeric)
是括号中的单个值,产生Numeric
所以这一行与:
say .first: Numeric given <abc 2 def ghi> ; # 2
但如果括号中有两个或多个参数,事情就会出错。使用以下形式之一:
say .first: Numeric, :k given <abc 2 def ghi> ; # 1
say .first(Numeric, :k) given <abc 2 def ghi> ; # 1
这正确地产生了数组索引(“key”)2
元素而不是:
say .first: (Numeric, :k) given <abc 2 def ghi> ; # Nil
这产生Nil
因为.first
方法对 a 没有做任何有用的事情single参数是表单的列表(Numeric, :k)
.
当然,你也可以偶尔want传递一个参数,该参数是括号中的值列表。但您可以不使用冒号来完成此操作。为了清楚起见,我建议您将其写为:
invocant.a-method(( valuea, valueb, ... ));
a-sub ( arrgh1, arrgh2, ... ) ;
正如刚才对方法调用所解释的,这将一个参数传递给a-sub
,即单个列表( arrgh1, arrgh2, ... )
这很少是作者的意思。
同样,我的建议是将其写为:
`a-sub( valuea, valueb, ... ) ;`
or:
`a-sub valuea, valueb, ... ;`
如果您打算传递多个参数,或者希望将列表作为单个参数传递,那么:
`a-sub(( valuea, valueb, ... )) ;`
.a-method : arrgha, arrghb, ...
a-sub : arrgha, arrghb, ...
对于方法形式,这会给你一个“混乱”的编译错误。
对于子表单来说也是如此,如果a-sub
不接受任何争论。如果a-sub
接受参数你会得到一个“前面的上下文需要一个术语,但发现中缀:相反”编译错误。
.&a-sub
有一种调用形式可以让您调用声明为子程序的例程——但是使用.method
调用语法。以下为“调用者”提供信息qux
在点的左边作为名为的子函数的第一个参数a-sub
:
qux.&a-sub
Use a :
或照常使用括号传递额外的论点a-sub
:
sub a-sub ($a, $b) { $a == $b }
say 42.&a-sub(42), 42.&a-sub(43); # TrueFalse
say 42.&a-sub: 42; # True
(在本节的原始版本中,我写道,一个人不能传递额外的参数。我已经对此进行了测试,并认为一个人不能。但我一定是被某些东西弄糊涂了。@Enheh 的评论让我重新测试并发现一个can就像普通方法调用一样传递附加参数。谢谢@Enheh。 :))
a-method( invocant: arg2, arg3, ... )
a-method invocant: arg2, arg3, ...
在设计文档中称为“间接对象表示法”,这些格式是一种未记录且很少见的方法调用形式,其中调用模仿方法声明 - 方法名称在前,然后是调用者,后跟冒号:
say first <abc 2 def ghi>: Numeric ; # 2
注意say
is a sub调用因为下一个令牌,first
, 后面没有冒号。相比之下first
is a method调用,因为它后面的令牌is后面跟着一个冒号。
脚注
1 All comments about spaces/spacing in this answer ignore unspacing.