可能重复: Why is Perl foreach variable assignment modifying the values in the array?
似乎子例程参数是按值传递的,但在下面的示例中,它是通过引用传递的:
@a = (3,5,7);
foreach my $b (@a) {
$b = 8;
}
print "@a"; # 888
那么Perl的设计原则是什么,以便我们能够清楚地知道我们现在是否正在处理原始数据的副本?
答案 0 :(得分:4)
你的例子不是一个子程序,所以它并没有真正“传递”任何东西。
你拥有的是一个数组(3,5,7),每个我的$ b是对数组中每个元素的引用。你可以想到这种情况,因为你在遍历数组中的元素,而不是遍历它们的副本。
无论何时引用数组中的元素,都会引用THE元素,而不是副本。
答案 1 :(得分:3)
Perl在这种情况下对scalars有些神奇地对待,并且sorta“假装”它通过引用传递它们。有时它很有用,有时候后面很痛。
啊哈,在Programming Perl, chapter 4中找到了参考和解释:
如果LIST完全由可赋值(意味着变量,通常不是枚举常量)组成,则可以通过修改循环内的VAR来修改每个变量。这是因为foreach循环索引变量是您循环的列表中每个项目的隐式别名。
感谢ysth提供以下官方perl documentation的参考资料:
如果LIST的任何元素是左值,您可以通过修改循环内的VAR来修改它。相反,如果LIST的任何元素不是左值,则任何修改该元素的尝试都将失败。换句话说,foreach循环索引变量是您循环的列表中每个项的隐式别名。