我知道perl中的子程序通过引用传递arg。但是在下面的代码中,子例程中的foreach循环不应该更改@list
的值,因为my $i
应该创建一个新的词法范围var $i
。对$i
的任何分配都应该是词汇范围,但不能更改@list
值。
有人能解释一下foreach循环中发生的变化导致值变为@list
吗?
sub absList {
foreach my $i (@_) {
$i = abs($i);
}
}
@list = (-2,2,4,-4);
absList(@list);
print "@list";
输出:
2 2 4 4
答案 0 :(得分:5)
$i
使@_
数组{@ 3}}元素的元素别名(并且@_
元素别名@list
到期@_
元素} foreach
)。
来自magic
如果LIST的任何元素是左值,您可以通过修改循环内的VAR来修改它。相反,如果LIST的任何元素不是左值,则任何修改该元素的尝试都将失败。换句话说,foreach循环索引变量是列表中每个项目的隐式别名。
如果您想避免此类行为,请不要直接在@_
数组上进行迭代,即
sub absList {
my @arr = @_;
foreach my $i (@arr) {
$i = abs($i);
}
}
答案 1 :(得分:2)
$i
这里引用了从@_
获取的列表元素,这就是为什么更改$i
会导致相应列表元素发生更改的原因。