Perl 6 中嵌套列表的赋值

Assignment to nested lists in Perl 6

我想,结果应该是1, 2, 3

> my ($a, $b, $c)
> (($a, $b), $c) = ((1, 2), 3)
(((1 2) 3) (Any))
> $a, $b, $c
((1 2) 3 (Any))

这是怎么回事?

如果你想让结果是 1, 2, 3,你必须 Slip 列表:

my ($a, $b, $c) = |(1, 2), 3;

这是单参数规则的结果:https://docs.raku.org/type/Signature#Single_Argument_Rule_Slurpy

这也是为什么它有效的原因:

my ($a, $b, $c) = (1, 2, 3);

即使 (1,2,3) 是一个包含 3 个元素的 List,它也会因为相同的单参数规则而被自动滑动。您当然也可以只删除(迷信的)括号:

my ($a, $b, $c) = 1, 2, 3;

没什么问题(也就是说,P6 中的普通赋值是设计成它已经完成的)但是你猜测你希望使两侧的结构相同会导致 $a获得 1$b 获得 2$c 获得 3.

为此,您需要 "binding assignment"(也就是 "binding"),而不是普通赋值:

my ($a, $b, $c);
:(($a, $b), $c) := ((1, 2), 3);

注意左侧列表前的冒号,使其成为签名文字,并注意 = 前的冒号,使其成为绑定操作。

你在问 *这里出了什么问题",我会说 the single argument rule 的一些变体在起作用。由于括号在这里仅用于分组,所以发生的是这个赋值

($a, $b), $c = (1, 2), 3

(1, 2), 3 表现为单个参数,因此它们被分配给组中的第一个元素 $a, $b。因此他们得到了一切,而旧的 $c 只得到了 Any。这样看:

my ($a, $b, $c); 
($a, ($b, $c)) = ((1, 2), 3, 'þ'); 
say $a, $c; # OUTPUT: «(1 2)þ␤»

您可能想查看 this code by Larry Wall, which uses »=«, which does exactly what you are looking for. It's not documented,因此您可能需要稍等片刻。