arrays - Raku 列表加法运算符“Z+”“失败”,除非强制使用列表之一
问题描述
我很难理解为什么 zip-addZ+
运算符在某些情况下不起作用。
我有一些我想总结的 2 元素列表。
无论我使用列表还是数组,这些都按预期工作:
say (1, 2) Z+ (3, 4) # (4, 6)
say [1, 2] Z+ (3, 4) # (4, 6)
say [1, 2] Z+ [3, 4] # (4, 6)
say (1, 2) Z+ [3, 4] # (4, 6)
现在我们将做同样的事情,但我将使用存储在其他地方的值更改正确的操作数。在这种情况下,我有一个列表数组:
my @foo = (1,1), (2,2);
say @foo.WHAT; # (Array)
say @foo[1].WHAT; # (List)
say @foo[1]; # (2,2)
say (3,3) Z+ @foo[1]; # (5) ???
这给出了意想不到的(至少对我来说:))结果(5)
。
有几种方法可以解决这个问题。
第一个是强制得到的元素是一个列表:
my @foo = (1,1), (2,2);
say @foo.WHAT; # (Array)
say @foo[1].WHAT; # (List) <== It was already a list, but...
say @foo[1]; # (2,2)
say (3,3) Z+ @foo[1].list; # <== changed. (5,5)
另一种是将@foo
定义更改为列表而不是数组(通过is List
或绑定:=
值)
my @foo is List = (1,1), (2,2); # <=== Changed
say @foo.WHAT; # (Array)
say @foo[1].WHAT; # (List) <== It was already a list
say @foo[1]; # (2,2)
say (3,3) Z+ @foo[1]; # (5,5)
为什么第一个案例不起作用?
解决方案
如果您+
从 中删除Z
,并使用dd
而不是say
,它可能会变得更清晰:
dd (3,3) Z @foo[1]; # ((3, $(2, 2)),).Seq
所以在这种情况下,你会得到一个带有3
and的列表(2,2)
。注意:$
之前的(2,2)
,这意味着它是逐项列出的:被视为单个项目。
现在Z+
,您将添加值,而不是创建列表。
当你写:
say 3 + (42,666); # 5
你得到5
是因为你将列表中的元素数量添加到3
. 这就是您5
在示例中也结束的原因,而不是因为列表中的值是2
.
在其他情况下,Z
操作员会看到非逐项列表,因此将按照您的预期迭代其元素。
如有疑问,请确保您使用dd
而不是say
调试:它将为您提供表达式的本质,而不仅仅是“要点”:-)