首页 > 解决方案 > 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)

为什么第一个案例不起作用?

标签: arrayslistrakurakudo

解决方案


如果您+从 中删除Z,并使用dd而不是say,它可能会变得更清晰:

dd (3,3) Z @foo[1];  # ((3, $(2, 2)),).Seq

所以在这种情况下,你会得到一个带有3and的列表(2,2)。注意:$之前的(2,2),这意味着它是逐项列出的:被视为单个项目。

现在Z+,您将添加值,而不是创建列表。

当你写:

say 3 + (42,666);    # 5

你得到5是因为你将列表中的元素数量添加到3. 这就是您5在示例中也结束的原因,而不是因为列表中的值是2.

在其他情况下,Z操作员会看到非逐项列表,因此按照您的预期迭代其元素。

如有疑问,请确保您使用dd而不是say调试:它将为您提供表达式的本质,而不仅仅是“要点”:-)


推荐阅读