将数组强制转换为列表时行为不一致?

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 被强制为列表时很重要?

Mus*_*dın 7

@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)