Perl 6 签名中的匿名参数是否会丢弃该值?
Does an anonymous parameter in a Perl 6 signature discard the value?
在 Perl 6 Signature docs 中,有一个匿名 slurpy 参数的例子:
sub one-arg (@) { }
sub slurpy (*@) { }
one-arg (5, 6, 7); # ok, same as one-arg((5, 6, 7))
slurpy (5, 6, 7); # ok
slurpy 5, 6, 7 ; # ok
子例程中没有语句,主要是因为围绕它的文本是关于满足签名的参数列表,而不是子例程用它做什么。
我正在玩它并尝试制作一个子例程,该子例程采用多个项目之一的列表(因此,不是零项目)。我并没有特别在意给他们起名字。我认为即使有签名,我仍然可以访问 @_
中的参数列表。但是,当您没有签名时,您会得到 @_
:
$ perl6
To exit type 'exit' or '^D'
> sub slurpy(*@) { say @_ }
===SORRY!=== Error while compiling:
Placeholder variable '@_' cannot override existing signature
------> sub⏏ slurpy(*@) { say @_ }
是否有其他方法获取参数列表,或者匿名参数是否丢弃它们?我看到它们在有关类型约束的部分中使用,但没有使用任何参数值的示例。我还能得到参数列表吗?
要填充 @_
,签名必须是隐式的或显式的,不能两者兼而有之。
sub implicit { say @_ } # most like Perl 5's behaviour
sub explicit ( *@_ ) { say @_ }
sub placeholder { $^a; say @_ }
这也适用于方块
my &implicit = { say @_ }
my &explicit = -> *@_ { say @_ }
my &placeholder = { $^a, say @_ }
块也可以有一个隐式参数 $_
,但如果有 @_
则优先。
{ say $_ }(5) # 5
$_ = 4;
{ @_; say $_ }(5) # 4
这样做是有意义的,因为一个程序员可能认为它按照您认为的方式工作,或者它像隐式的那样笨拙,而另一个程序员可能认为它获得了所有剩余的参数.
sub identical ( @_ ) { say @_ }
sub slurpy ( *@_ ( @, *@ ) ) { say @_ } # same as implicit
sub slurpy2 ( **@_ ( @, *@ ) ) { say @_ } # non-flattening
sub remaining ( @, *@_ ) { say @_ }
identical [1,2]; # [1 2]
slurpy $[1,2],3,4,5; # [[1 2] 3 4 5]
slurpy2 [1,2],3,4,5; # [[1 2] 3 4 5]
remaining [1,2],3,4,5; # [3 4 5]
@_
也可能会被添加为错误,在这种情况下最好产生错误。
如果不声明捕获参数,就无法获取原始参数。
sub raw-one ( |capture ( @ ) ) { capture.perl }
sub raw-slurpy ( |capture, *@ ) { capture.perl }
raw-one [1,2]; # \([1, 2])
raw-slurpy 1,2 ; # \(1, 2)
Does an anonymous parameter in a Perl 6 signature discard the value?
是的,除非您使用函数签名中的某个命名参数捕获参数,否则它在函数体中不可用。 (PS:不过,正如莫里茨的回答所示,它们并没有真正被丢弃。)
I figured I'd still have access to the argument list in @_ even with the signature.
@_
不是使用参数的替代方法 - 它 是 一个参数。
每个函数都有一个明确定义的签名来指定其参数,它们代表了函数体获取函数传递值的唯一机制。
只是函数签名的声明方式有3种不同:
- 如果您明确写出一个签名,那就是使用的签名。
- 如果您在函数体中使用 占位符参数(
@_
或 $^foo
等),编译器会使用该信息来构建给你的签名:say { $^a + @_ }.signature; # ($a, *@_)
- 如果以上都不是,则签名变为:
- 在子程序的情况下,接受零参数的子程序:
say (sub { 42 }).signature; # ()
- 在裸块的情况下,接受零个或一个可用参数的块
$_
:say { 42 }.signature; # (;; $_? is raw)
在所有情况下,函数在编译时都以明确的签名结束。 (尝试在已经具有显式签名的函数中使用 $^foo
是编译时错误。)
Is there another way to get the argument list
确保使用非匿名参数捕获它。如果您希望它可以作为 @_
访问,则在您正在编写的显式签名中调用它。
I was [...] trying to make a subroutine that takes a list of one of more items
您可以为此使用子签名:
sub foo (*@_ [$, *@]) { ... };
或者 where
约束:
sub foo (*@_ where .so) { ... };
这些值没有被丢弃;例如,您可以通过 nextsame:
访问它
multi access-anon(*@) is default {
say "in first candidate";
nextsame;
}
multi access-anon(*@a) {
@a;
}
say access-anon('foo')
输出:
in first candidate
[foo]
但要获得原始 objective(至少包含一个元素的数组),您实际上并不需要访问该列表;您可以使用子签名:
sub at-least-one(@ [$, *@]) { }
at-least-one([1]); # no error
at-least-one([]); # Too few positionals passed; expected at least 1 argument but got only 0 in sub-signature
在 Perl 6 Signature docs 中,有一个匿名 slurpy 参数的例子:
sub one-arg (@) { }
sub slurpy (*@) { }
one-arg (5, 6, 7); # ok, same as one-arg((5, 6, 7))
slurpy (5, 6, 7); # ok
slurpy 5, 6, 7 ; # ok
子例程中没有语句,主要是因为围绕它的文本是关于满足签名的参数列表,而不是子例程用它做什么。
我正在玩它并尝试制作一个子例程,该子例程采用多个项目之一的列表(因此,不是零项目)。我并没有特别在意给他们起名字。我认为即使有签名,我仍然可以访问 @_
中的参数列表。但是,当您没有签名时,您会得到 @_
:
$ perl6
To exit type 'exit' or '^D'
> sub slurpy(*@) { say @_ }
===SORRY!=== Error while compiling:
Placeholder variable '@_' cannot override existing signature
------> sub⏏ slurpy(*@) { say @_ }
是否有其他方法获取参数列表,或者匿名参数是否丢弃它们?我看到它们在有关类型约束的部分中使用,但没有使用任何参数值的示例。我还能得到参数列表吗?
要填充 @_
,签名必须是隐式的或显式的,不能两者兼而有之。
sub implicit { say @_ } # most like Perl 5's behaviour
sub explicit ( *@_ ) { say @_ }
sub placeholder { $^a; say @_ }
这也适用于方块
my &implicit = { say @_ }
my &explicit = -> *@_ { say @_ }
my &placeholder = { $^a, say @_ }
块也可以有一个隐式参数 $_
,但如果有 @_
则优先。
{ say $_ }(5) # 5
$_ = 4;
{ @_; say $_ }(5) # 4
这样做是有意义的,因为一个程序员可能认为它按照您认为的方式工作,或者它像隐式的那样笨拙,而另一个程序员可能认为它获得了所有剩余的参数.
sub identical ( @_ ) { say @_ }
sub slurpy ( *@_ ( @, *@ ) ) { say @_ } # same as implicit
sub slurpy2 ( **@_ ( @, *@ ) ) { say @_ } # non-flattening
sub remaining ( @, *@_ ) { say @_ }
identical [1,2]; # [1 2]
slurpy $[1,2],3,4,5; # [[1 2] 3 4 5]
slurpy2 [1,2],3,4,5; # [[1 2] 3 4 5]
remaining [1,2],3,4,5; # [3 4 5]
@_
也可能会被添加为错误,在这种情况下最好产生错误。
如果不声明捕获参数,就无法获取原始参数。
sub raw-one ( |capture ( @ ) ) { capture.perl }
sub raw-slurpy ( |capture, *@ ) { capture.perl }
raw-one [1,2]; # \([1, 2])
raw-slurpy 1,2 ; # \(1, 2)
Does an anonymous parameter in a Perl 6 signature discard the value?
是的,除非您使用函数签名中的某个命名参数捕获参数,否则它在函数体中不可用。 (PS:不过,正如莫里茨的回答所示,它们并没有真正被丢弃。)
I figured I'd still have access to the argument list in @_ even with the signature.
@_
不是使用参数的替代方法 - 它 是 一个参数。
每个函数都有一个明确定义的签名来指定其参数,它们代表了函数体获取函数传递值的唯一机制。
只是函数签名的声明方式有3种不同:
- 如果您明确写出一个签名,那就是使用的签名。
- 如果您在函数体中使用 占位符参数(
@_
或$^foo
等),编译器会使用该信息来构建给你的签名:say { $^a + @_ }.signature; # ($a, *@_)
- 如果以上都不是,则签名变为:
- 在子程序的情况下,接受零参数的子程序:
say (sub { 42 }).signature; # ()
- 在裸块的情况下,接受零个或一个可用参数的块
$_
:say { 42 }.signature; # (;; $_? is raw)
- 在子程序的情况下,接受零参数的子程序:
在所有情况下,函数在编译时都以明确的签名结束。 (尝试在已经具有显式签名的函数中使用 $^foo
是编译时错误。)
Is there another way to get the argument list
确保使用非匿名参数捕获它。如果您希望它可以作为 @_
访问,则在您正在编写的显式签名中调用它。
I was [...] trying to make a subroutine that takes a list of one of more items
您可以为此使用子签名:
sub foo (*@_ [$, *@]) { ... };
或者 where
约束:
sub foo (*@_ where .so) { ... };
这些值没有被丢弃;例如,您可以通过 nextsame:
访问它multi access-anon(*@) is default {
say "in first candidate";
nextsame;
}
multi access-anon(*@a) {
@a;
}
say access-anon('foo')
输出:
in first candidate
[foo]
但要获得原始 objective(至少包含一个元素的数组),您实际上并不需要访问该列表;您可以使用子签名:
sub at-least-one(@ [$, *@]) { }
at-least-one([1]); # no error
at-least-one([]); # Too few positionals passed; expected at least 1 argument but got only 0 in sub-signature