perl foreach循环子程序

时间:2014-06-07 12:23:51

标签: perl foreach subroutine

我知道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

2 个答案:

答案 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会导致相应列表元素发生更改的原因。