我很难理解在推送Scalar
之后何时以及为什么推送的容器所持有的价值会受到影响。我将在两个风格化的示例中尝试更复杂地说明我遇到的问题。
*示例1 *在第一个示例中,标量作为a的一部分$i
被推到数组@b
上List
。推送之后,使用$i++
指令在for循环的后续迭代中显式更新标量所拥有的值。这些更新会影响数组中的值@b
:在for循环的末尾,@b[0;0]
等于3
,不再等于2
。
my @b;
my $i=0;
for 1..3 -> $x {
$i++;
say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
if $x == 2 {
@b.push(($i,1));
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
}
}
say "Post for-loop";
say "Array : ", @b;
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
输出示例1:
Loose var $i: Scalar|94884317665520 139900170768608
Loose var $i: Scalar|94884317665520 139900170768648
Pushed $i : Scalar|94884317665520 139900170768648
Loose var $i: Scalar|94884317665520 139900170768688
Post for-loop
Array : [(3 1)]
Pushed $i : Scalar|94884317665520 139900170768688
*示例2 *在第二个示例中,标量$i
是循环变量。尽管$i
它已被推后(现在的隐含而不是明确地)的值更新$i
数组@c
并没有
推后更改; 即在for循环之后,它仍然2
不是3
。
my @c;
for 1..3 -> $i {
say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
if $i == 2 {
@c.push(($i,1));
say 'Pushed $i : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;
}
}
say "Post for-loop";
say "Array : ", @c;
say 'Pushed $i : ', @c[0;0].VAR.WHICH, " ", @c[0;0].VAR.WHERE;;
输出示例2:
Loose var $i: Scalar|94289037186864 139683885277408
Loose var $i: Scalar|94289037186864 139683885277448
Pushed $i : Scalar|94289037186864 139683885277448
Loose var $i: Scalar|94289037186864 139683885277488
Post for-loop
Array : [(2 1)]
Pushed $i : Scalar|94289037186864 139683885277448
问:为什么$i
在@b
例1推后更新,而$i
在@c
例2中是不是?
编辑:在@timotimo的评论之后,我.WHERE
在示例中包括的输出。这显示了保持的(WHICH /逻辑)标量身份$i
不变,而其内存地址通过各种循环迭代而改变。但是,这并没有解释为什么在示例2中,推入的标量与旧地址(“ 448”)结合仍然与同一WHICH身份绑定。
.WHERE
而不是,.WHICH
则每次循环时,标量实际上都是一个不同的对象。之所以会这样,是因为尖锐的块被“调用”,并且签名在每次调用时都被“绑定”。