0

为什么

my $i=0;
my @arr=();

sub readall {
    foreach (@_) {
        $arr[$i] = shift @_;
        $i++;
    }
}

readall(1, 2, 3, 4, 5);
print "@arr"

my $i=0;
my @arr=();

sub readall {
    foreach (@_) {
        $arr[$i] = shift @_;
        print $arr[$i];
        $i++;
    }
}

readall(1, 2, 3, 4, 5);

只打印三个参数到readall?

为什么这个看起来应该表现相同的函数处理所有五个参数?

sub readall {
    foreach (@_) {
        print $_;
    }
}

readall(1, 2, 3, 4, 5);

这也读取所有五个(但确实以不同的原则运作):

my @arr=();

sub readall {
    push(@arr, @_);
}

readall(1, 2, 3, 4, 5);
print "@arr"
4

4 回答 4

6

在同一个数组上使用foreachand可能会引起混淆。shift两个失败的都使用它,两个都没有..不要。

只是更改shift @_$_修复它。

发生这种情况是因为您在迭代时正在缩短数组。

于 2013-01-13T14:08:38.047 回答
4

您遍历 中的所有参数@_,同时移动@_以使其更短:

sub readall {foreach (@_) {$arr[$i]=shift @_ ....}

让这里的优秀列表解释在这种情况下的预期,记录的内容以及为什么不应该这样做。对我来说,这在逻辑上是错误的,没有任何意义。也许s/foreach/while/更惯用(至少,它有效)。

于 2013-01-13T14:10:03.483 回答
4

每次移动阵列时,它都会变短......所以你不是在整个阵列上操作,它会提前停止。您可以通过在代码中添加一行来看到这一点:

perl -wlae 'my $i=0; my @arr=(); sub readall {foreach (@_) {$arr[$i]=shift @_; $i++; print @_;}} readall(1,2,3,4,5); print "@arr"'

2345
345
45

我想你可以从这里弄清楚。

于 2013-01-13T14:10:07.353 回答
4

shift @_inside offoreach (@_)是错误的,摆脱它可以修复数组遍历:

$ perl -wlae 'my $i=0; my @arr=(); sub readall {foreach (@_) {$arr[$i]=$_[$i]; $i++}} readall(1,2,3,4,5); print "@arr"'
1 2 3 4 5

foreach引用$_数组的每个元素工作:

$ perl -wlae 'my @arr=(1..5);foreach (@arr) { $_ *= 2 }; foreach (@arr) { print }'
2
4
6
8
10

unshift因此,使用/取消引用元素pop会使一切变得混乱。

于 2013-01-13T14:11:05.993 回答