这篇文章主要讲述的是一个未去容器化的 Scalar
。
你可以将return $d
修改为return @$d
有一个选项可以获得相同的行为,即修改b
例程。
你写到“这些子例程都返回一个数组,但是返回的数组行为不同。”,但是如Holli所指出的那样,b
实际上返回了绑定到$d
的 Scalar
(它转而包含一个数组):
sub b { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().VAR.WHAT; # (Scalar)
您可以通过“取消容器化”$d
来更改它,例如通过在前面添加@
:
sub b { my $d = [ 1, 2, 3, 4 ]; return @$d };
say b().VAR.WHAT;
my @f = b();
say @f;
say @f[1];
或者将@f = b()
改为@f = b[]
如果您不对b
返回的值进行去容器化,则会出现第二个问题/机会。
无论b
返回什么,都将评估分配给@f
的值列表。在列表上下文中,Scalar
保持不变(就像使用简单的return $d
一样)。因此,如果您不更改b
以消除容器,则需要在分配给@f
时进行,如果要使@e
和@f
最终相同。
这次你不能只是添加@
就行了。因为那会拼写成@b
,Raku会将其解释为一个@b
变量。
一种方法是编写@f = @(b())
,但这样会显得丑陋/非惯用语。另一种选择是编写@f = b[]
。这利用了b
调用中的括号是多余的事实。附加[]
("禅片")具有与编写@(b)
相同的效果,但字符少一个。
因此,要在列表分配中进行去容器化,您可以编写:
sub b { my $d = [ 1, 2, 3, 4 ]; return $d };
say b().VAR.WHAT;
my @f = b[];
say @f;
say @f[1];
"明确文档中的内容"
在文档中,如何表述清楚子程序返回的内容是哪种数组类型?
即使将问题转换为"返回的是什么",我也不确定您的意思。
我也不确定应该在文档中指向什么地方,甚至不确定是否有任何与您在 Stack Overflow 场景相关的好的指向。
我知道如果是我的话,相对于您的场景,我会发现以下文档部分比较困惑:
Holli 提供的 Scalar containers and listy things 部分。对我来说,该部分目前似乎涉及在列表/数组中使用 Scalar
容器,这与我上述第二个问题($d
在赋值给 @f
的列表中)相关。但这与我所提到的第一个问题无关(从 b
子例程中返回 $d
)。在那种情况下,情况恰恰相反,即一个数组在 Scalar
内部。
同一页中的 Scalar containers 部分。开头的句子——"尽管 Raku 中到处都是 Scalar
类型的对象,但您很少直接看到它们作为对象,因为大多数操作会取消容器化..." 对我来说没问题。但是 "如果将其标记为 is rw
,则例程可以返回容器" 更具有争议性。这是真的:
my $x = 23;
sub f() is rw { $x };
f() = 42;
say $x; # OUTPUT: «42»
但是,并不一定需要将例程标记为 is rw
才能返回容器。可以使用 return
例程,就像您所做的那样:
my $x = 23;
sub f() { return $x };
say f().VAR.WHAT; # OUTPUT: «Scalar»