Arrays Raku列表加法运算符'Z+;`';失败';除非其中一个列表是强制的
我很难理解为什么zip addArrays Raku列表加法运算符'Z+;`';失败';除非其中一个列表是强制的,arrays,list,raku,rakudo,Arrays,List,Raku,Rakudo,我很难理解为什么zip addZ+操作符在某些情况下不起作用 我有一些两个元素的列表,我想总结一下 无论我使用的是列表还是数组,它们都能正常工作: 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 =
Z+
操作符在某些情况下不起作用
我有一些两个元素的列表,我想总结一下
无论我使用的是列表还是数组,它们都能正常工作:
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)
的意外结果(至少对我来说:)
有几种方法可以解决这个问题
第一个是强制get元素成为列表:
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)
为什么第一个案例不起作用?如果从
Z
中删除+
,并使用dd
而不是say
,它可能会变得更清晰:
dd (3,3) Z @foo[1]; # ((3, $(2, 2)),).Seq
因此,在本例中,您将得到一个带有3
和(2,2)
的列表。注意$
前面的(2,2)
:这意味着它被逐项列出:被视为单个项目
现在使用Z+
,您将不创建列表,而是添加值
当你写作时:
say 3 + (42,666); # 5
您将获得5
,因为您正在将列表中的元素数添加到3
。这就是为什么您在示例中也使用了5
,而不是,因为列表中的值是2
在其他情况下,Z
操作符会看到非逐项列表,因此会像您预期的那样迭代其元素
如果有疑问,请确保在调试中使用
dd
而不是say
:它将为您提供表达式的本质,而不仅仅是“要点”:-另一种看待事物的方式
my @foo = (1,1), (2,2);
say @foo.WHAT; # (Array)
say @foo[1].WHAT; # (List) <== It was already a list, but...
我将提请注意上述几个方面:
- 标量通常对自己保持沉默
返回它在上下文中包含的值,除非您使用Scalar
显式查找它.VAR
容器可以是读/写或只读的 在我写下这个答案之前,我并没有将这一方面清晰地整合到我对Raku使用Scalar
s的理解中。也许这对其他人来说是显而易见的,但我觉得在这里值得一提,因为Scalar
和dd
中的.raku
显示所指示的$(…)
标量是只读的,您无法分配给它
“自动激活”其每个元素的读/写数组
如果一个值被分配给一个(非本机的)标量
数组的索引位置(比如
),那么如果该元素当前不存在(即@foo[42]
为@foo[42]:exists
),则新的读/写False
是“自动激活的”(自动创建并绑定到该索引位置)作为处理分配的第一步标量
从不为其任何元素自动激活列表
当一个值被“分配”(实际绑定,即使使用了“分配”一词)到标量
列表中的索引位置时,不会发生自动激活。
列表可以包括
标量
s,包括读/写的,但唯一可能发生的方法是如果现有的读/写
标量
被“分配”到元素(索引位置),例如
my@foo:=(42,$=99);@foo[1]=100;说@foo;#(42 100)
现在我们可以理解您的代码,它产生
(5)
:
†我们将强制数字操作(
+
)应用于列表(位置
值),而不是其元素。强制为数字的列表是其“长度”(元素计数)。(当然是非稀疏的。我不确定稀疏的)。谢谢!为什么((1,1),)[0]
返回一个非逐项列表,但另一方面,[(1,1),][0]
返回一个逐项列表?@julio[,]
创建一个数组,该数组逐项列出其元素。(,)
创建一个列表,该列表不按默认值逐项列出谢谢!我未来的自我进一步阅读:
my @foo = (1,1), (2,2);
say @foo.WHAT; # (Array)
say @foo[1].WHAT; # (List) <== It was already a list, but...
my @foo = (1,1), (2,2);
say @foo.WHAT; # (Array)
say @foo[1].VAR.WHAT; # (Scalar) <== In reality it was a `Scalar`, not a `List`
say @foo[1].WHAT; # (List) <== The `Scalar` returns the value it contains
@foo[1] = 42; # Works. <== The `Scalar` supports mutability
my @foo2 is List = (1,1), (2,2);
say @foo2.WHAT; # (List) <== `List`s do *not* make `Scalar`s
say @foo2[1].VAR.WHAT; # (List) <== `VAR` on a non-`Scalar` is a no op
say @foo2[1].WHAT; # (List) <== This time `@foo2[1]` IS a *`List`*
@foo2[1] = ...; # Fails no matter what `@foo2[1]` and `...` are.
@foo2[1] := ...; # Fails no matter what `@foo2[1]` and `...` are.
my @foo = (1,1), (2,2); # `@foo` is bound to a fresh non-native `Array`
say @foo[1].VAR.WHAT; # (Scalar) -- @foo[1] is an autovivified `Scalar`
say @foo[1]; # (2,2) -- `say` shows value contained by `Scalar`
say (3,3) Z+ @foo[1]; # (5) --- because it's same as follows:
say +$(2,2); # 2 -- number of elements in a two element list †
say (3,3) Z+ 2; # (5) -- `Z` stops if either side exhausted