Raku中数组转List时机不同导致行为不一致的疑问
为什么Raku中数组赋值时的List强制转换时机会影响flat的结果?
以下是测试代码及输出:
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) # 这不是我预期的输出。 @foo = (1, (2, 3), (4, (5, 6), 7), (8), 9); say @foo.List.flat; # OUTPUT: (1 2 3 4 5 6 7 8 9) # 这是我预期的输出。 say $*DISTRO; # macos (12.6) say $*VM; # moar (2022.07) say $*RAKU; # Raku (6.d) say $*KERNEL; # darwin
核心原因在于Raku数组赋值的自动扁平化规则,以及List对象的特性:
调用
.List后赋值的场景:.List方法会把括号内的结构包装成一个单层不可变List对象,嵌套的括号会被保留为子List元素。数组@foo接收这个List时,只会将List的顶层元素作为自身元素,不会递归展开嵌套的子List。因此@foo的元素是:1、(2,3)、(4,(5,6),7)、8、9。调用.flat时默认只扁平化一层嵌套,子List不会被进一步展开,所以输出不符合预期。直接赋值列表字面量的场景:
直接给数组赋值列表字面量时,Raku会自动执行深度扁平化——递归展开所有嵌套的可迭代对象,直到得到单个元素。赋值完成后,@foo已经是完全展开的数组:1、2、3、4、5、6、7、8、9。后续调用.List.flat只是再次确认扁平化状态,输出自然符合预期。
如果想在第一种场景下得到完全扁平化的结果,可以先调用.deep方法深度展开List:
my @foo; @foo = (1, (2, 3), (4, (5, 6), 7), (8), 9).List.deep; say @foo.flat; # 输出 (1 2 3 4 5 6 7 8 9)
内容的提问来源于stack exchange,提问作者Jim Bollinger
相关产品推荐
相关产品推荐

