Jim*_*ger 7 arrays list coerce raku
my @foo;
@foo = (1, (2, 3), (4, (5, 6), 7), (8), 9).List;
say @foo.flat;
# OUTPUT: (1 (2 3) (4 (5 6) 7) 8 9)
# this is NOT the output I expected.
@foo = (1, (2, 3), (4, (5, 6), 7), (8), 9);
say @foo.List.flat;
# OUTPUT: (1 2 3 4 5 6 7 8 9)
# this is the output I expected.
say $*DISTRO; # macos (12.6)
say $*VM; # moar (2022.07)
say $*RAKU; # Raku (6.d)
say $*KERNEL; # darwin
Run Code Online (Sandbox Code Playgroud)
看来强制分配没有效果。
为什么 @foo 被强制为列表时很重要?
在@sigil中,文档指出
默认情况下,当您将 a 分配
List给 @-sigiled 变量时,您会创建一个Array.
其中“分配”指的是=,RHS 实际上不必是 List;之后my @f = ...,@f以数组类型结束。(在您的情况下,RHS 恰好是一个列表;事实上,它是一个已经包含文字的列表,因此您不需要.List那里)。
现在,由于@foo是一个数组,它将其元素放入标量 容器中,这可以抵抗扁平化,因此出现了您所看到的行为。
>>> my @foo = (1, (2, 3), (4, (5, 6), 7), (8), 9)
[1 (2 3) (4 (5 6) 7) 8 9]
>>> @foo.WHAT
(Array)
>>> @foo.flat
(1 (2 3) (4 (5 6) 7) 8 9)
Run Code Online (Sandbox Code Playgroud)
正如第一个链接中提到的,@foo如果您这样做,您可以获取列表my @foo := ...,即通过绑定,或显式覆盖位置上的默认类型,即my @foo is List = ...(或通过更改印记,例如my $foo := ......)。
对于第二种情况,@foo.List创建一个新的 List 对象@foo;所以没有标量容器,是的完全扁平化:
>>> @foo.List
(1 (2 3) (4 (5 6) 7) 8 9)
>>> @foo.List.WHAT
(List)
>>> @foo.List.flat
(1 2 3 4 5 6 7 8 9)
Run Code Online (Sandbox Code Playgroud)