在Perl中,它什么时候通过值/引用传递?

在Perl中,它什么时候通过值/引用传递?,perl,parameter-passing,Perl,Parameter Passing,可能重复: 子程序参数似乎是按值传递的,但在下面的示例中,它是按引用传递的: @a = (3,5,7); foreach my $b (@a) { $b = 8; } print "@a"; # 888 那么,Perl的设计原则是什么,以便我们能够很好地知道我们现在是否在处理原始数据的副本呢?Perl在这种情况下神奇地处理了标量,并且有点“假装”它在通过引用传递标量。有时是有用的,有时是后遗症 啊哈,找到了一个参考和解释: 如果列表完全由可赋值值(通常指变量,而不是枚举常量)组成,则

可能重复:

子程序参数似乎是按值传递的,但在下面的示例中,它是按引用传递的:

@a = (3,5,7);
foreach my $b (@a) {
    $b = 8;
}
print "@a"; # 888

那么,Perl的设计原则是什么,以便我们能够很好地知道我们现在是否在处理原始数据的副本呢?

Perl在这种情况下神奇地处理了标量,并且有点“假装”它在通过引用传递标量。有时是有用的,有时是后遗症

啊哈,找到了一个参考和解释:

如果列表完全由可赋值值(通常指变量,而不是枚举常量)组成,则可以通过修改循环中的VAR来修改这些变量中的每一个。这是因为foreach循环索引变量是循环列表中每个项目的隐式别名

感谢ysth提供以下官方参考:

如果列表中的任何元素是左值,可以通过在循环中修改VAR来修改它。相反,如果列表中的任何元素不是左值,任何修改该元素的尝试都将失败。换句话说,foreach循环索引变量是列表中要循环的每个项目的隐式别名


您的示例不是子例程,因此它不是真正的“传递”任何内容

您拥有的是一个数组(3、5、7),每个my$b都是对数组中每个元素的引用。您可以考虑这种情况,因为您正在迭代数组中的元素,而不是迭代它们的副本


任何时候引用数组中的元素,都是在引用元素,而不是副本。

是的,我第一次看到结果时非常惊讶,所以我想知道是否有什么一般规则可以遵循,这样我就可以轻松判断我是否在处理数据副本。@new\u perl:我终于找到了一个解释和引用。我更新了我的答案。我希望这是一个足够的答案。请不要链接到盗版书籍;更好的链接是。无论如何,编程Perl是错误的,官方Perl文档是正确的;列表不必是完全可赋值的,任何一个都可以修改。@ysth:谢谢你的提示,我用你的链接更新了我的答案,并将我的链接改为google books——希望这不是一个合法的灰色区域。等等,这里应该有一个子程序吗?@Ray Toal标题有点误导,但请观察分配给
$b
实际上是如何修改正在迭代的数组的。这与大多数其他语言不同。@Ray Toal和投票结束!;-)