sid*_*com 7 arrays documentation raku
sub a { my @c = 1, 2, 3, 4; return @c };
sub b { my $d = [ 1, 2, 3, 4 ]; return $d };
say a().WHAT; # (Array)
say b().WHAT; # (Array)
my @e = a();
my @f = b();
say @e; # [1 2 3 4]
say @e[1]; # 2
say @f; # [[1 2 3 4]]
say @f[1]; # (Any)
# valid raku code, no errors messages
Run Code Online (Sandbox Code Playgroud)
这些子例程都返回一个数组,但返回的数组行为不同。在文档中明确子例程返回哪种数组类型的正确表达式是什么?
sub b ( --> Array ) { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().WHAT; # (Array)
Run Code Online (Sandbox Code Playgroud)
sub b ( --> Scalar ) { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().WHAT;
# Type check failed for return value; expected Scalar but got Array ([1, 2, 3, 4])
# in sub b at ...
# in block <unit> at ...
Run Code Online (Sandbox Code Playgroud)
这完全是关于一个Scalar没有拆箱的。
return $d ---> return @$d获得相同行为的第一个机会是改变b常规。
您已经写过“这些子例程都返回一个数组,但返回的数组行为不同。”。但是,正如 Holli 所指出的,b而是返回Scalar绑定到$d(它又包含一个数组):
sub b { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().VAR.WHAT; # (Scalar)
Run Code Online (Sandbox Code Playgroud)
你可以通过 "decontainerizing" 来改变它$d,例如通过前置@:
sub b { my $d = [ 1, 2, 3, 4 ]; return @$d };
say b().VAR.WHAT; # (Array)
my @f = b();
say @f; # [1 2 3 4]
say @f[1]; # 2
Run Code Online (Sandbox Code Playgroud)
@f = b() ---> @f = b[]如果您不将 返回的值解容器化b,则会出现第二个问题/机会。
无论b返回什么,@f赋值都会评估被赋值给它的值列表。在列表上下文中,Scalars 保持原样(就像它们在普通 中一样return $d)。因此,如果您不更改b为 decontainerize,那么您需要在分配中这样做@f,如果您想要@e并且@f最终结果相同。
这一次你不能只是@准备这样做。因为那会拼写@b——Raku 会将其解释为一个@b变量。
一种选择是 write @f = @(b()),但这会很丑陋/不习惯。另一种选择是编写@f = b[]. 这利用了b调用中的括号是多余的这一事实。Appending [](“zen slice”)与 writing 具有相同的效果@(b),但少一个字符。
因此,要在列表分配中解容器,您可以编写:
sub b { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().VAR.WHAT; # (Scalar)
my @f = b[];
say @f; # [1 2 3 4]
say @f[1]; # 2
Run Code Online (Sandbox Code Playgroud)
在文档
中明确哪个数组类型是子例程返回的内容的正确表达式是什么?
我不确定您的这个问题是什么意思,即使切换到“返回的内容”也是如此。
我也不确定要在文档中指出什么,即使有任何好的地方可以指出,相对于您的 SO 中的场景。
我确实知道,如果是我,我会发现以下文档部分与您的场景相比令人困惑:
Holli 链接的标量容器和列表项部分。在我看来,该部分目前是关于Scalar在列表/数组中使用容器,这与我在上面写的第二个问题有关($d在分配给 的 rhs 的列表中@f)。但这与我写的第一个问题无关(return $d来自b例程)。事情正好相反,即在 a 中有一个数组Scalar。
该标容器部分前面在同一页上。开场白——“虽然类型的对象Scalar在 Raku 中无处不在,但你很少直接将它们视为对象,因为大多数操作都是去容器化的……”对我有用。但是“如果一个例程可以返回一个容器,如果它被标记为is rw”则问题更大。这是真的:
my $x = 23;
sub f() is rw { $x };
f() = 42;
say $x; # OUTPUT: «42?»
Run Code Online (Sandbox Code Playgroud)
但是,一个不具有标记例行is rw返回容器。可以return像您一样使用该例程:
my $x = 23;
sub f() { return $x };
say f().VAR.WHAT; # OUTPUT: «Scalar?»
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |