我正在寻找解释为什么这两个数据结构不相等:
$ perl6 -e 'use Test; is-deeply [ { a => "b" } ], [ { a => "b" }, ];'
not ok 1 -
# Failed test at -e line 1
# expected: $[{:a("b")},]
# got: $[:a("b")]
哈希和数组中的尾随逗号与P5一样没有意义:
$ perl6 -e '[ 1 ].elems.say; [ 1, ].elems.say'
1
1
但是如果没有它,哈希就会以某种方式丢失并且变得扁平化为对阵:
$ perl6 -e '[ { a => "b", c => "d" } ].elems.say;'
2
我怀疑一些Great List Refactor法律适用于此,但我想获得更详细的解释,以了解这种扁平化背后的逻辑。
答案 0 :(得分:6)
哈希和数组中的尾随逗号与P5一样没有意义
不,它没有意义:
(1 ).WHAT.say ; # (Int)
(1,).WHAT.say ; # (List)
Great List Refactor的大简化是为了迭代功能 1 切换到the single argument rule。也就是说,像for
或数组和哈希作曲家(和下标)这样的功能总是得到一个参数。这确实是你原来的例子。
单个参数可能是 - 通常是 - 一个值列表,甚至可能是列表列表等,但顶级列表仍然是迭代特征的单个参数。
如果迭代特性的单个参数执行Iterable角色(例如列表,数组和散列),那么它将被迭代。 (这是一个不精确的表述;请参阅my answer至"何时调用迭代器方法?"更精确的方法。)
因此,关于额外逗号的关键是要注意,如果单个参数不执行Iterable
角色,例如1
,那么最终结果如果参数是一个仅包含该值的列表(即1,
),则完全相同:
.perl.say for {:a("b")} ; # :a("b") Iterable Hash was iterated
.perl.say for {:a("b")} , ; # {:a("b")} Iterable List was iterated
.perl.say for 1 ; # 1 Non Iterable 1 left as is
.perl.say for 1 , ; # 1 Iterable List was iterated
典型的方式"在声明单个元素列表时使用尾随逗号来保留结构[除了]以外#34; (见下面的评论),即
停止正常迭代的单个Iterable
值,通过 item - 使用$
进行迭代:
my @t = [ $[ $[ "a" ] ] ];
@t.push: "b";
@t.perl.say; # [[["a"],], "b"]
1 迭代用于获取在for
的情况下传递给某些代码的值;获取值以成为在作曲家的情况下构造的数组/散列的元素;在下标的情况下获得索引切片;等等其他迭代特征。