和我的一样上一个问题 https://stackoverflow.com/questions/69137422/confusing-fmt-behavior-with-nested-lists,这是一个我无法判断我对 Raku 语义的理解是否遇到错误或漏洞的区域。上次竟然是bug,不过怀疑闪电会劈两次!
一般来说,我知道我可以使用看起来很像创建 Pair 的语法将命名参数传递给函数(例如f :a(42)
) 或语法为看起来很像 https://twitter.com/jnthnwrthngtn/status/1432395855819063301展平哈希(例如,f |%h
). (see 论证解构 https://docs.raku.org/type/Signature#index-entry-destructuring_arguments在文档中)。通常,这两者是等效的,即使对于非标量参数也是如此:
sub f(:@a) { dd @a }
my %h = a => [4, 2];
f :a([4,2]); # OUTPUT: «Array element = [4, 2]»
f |%h; # OUTPUT: «Array element = [4, 2]»
但是,当使用默认构造对象时.new
构造函数,这两种形式似乎给出了不同的结果:
class C { has @.a; }
my %h = a => [4, 2];
C.new: :a([4,2]; # OUTPUT: «C.new(a => ([[4, 2]])»
C.new: |%h; # OUTPUT: «C.new(a => [[4, 2],])»
也就是说,通过:a([4,2])
会产生一个二元素数组,但使用参数扁平化语法会产生一个包含二元素数组的单元素数组。
这种行为是故意的吗?如果是这样,为什么?我可以使用语法来传递|%h
并获取绑定到一个的二元素数组@
- 签名属性? (我知道使用$
-sigiled 属性有效,但我更喜欢的语义@
).