【问题标题】:Why does this Perl function appear to process only some of its arguments?为什么这个 Perl 函数似乎只处理它的一些参数?
【发布时间】:2012-12-27 13:44:39
【问题描述】:

为什么

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"

【问题讨论】:

  • 如果您发布正确的脚本而不是 100 字符长的单行文字,您的帖子会更容易阅读。如果您使用适当的编辑器,您还会获得语法高亮显示。
  • 谢谢你们帮了大忙。感谢@Mat 的建议,我会尝试。

标签: perl arguments argument-passing


【解决方案1】:

foreach (@_) 内部的shift @_ 是错误的,去掉它可以修复数组遍历:

$ 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 取消引用元素会搞砸一切。

【讨论】:

    【解决方案2】:

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

    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
    

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

    【讨论】:

    • 请注意,明确不支持修改(添加或删除元素)您正在循环的数组。如果您希望这样做,请改为遍历索引:for (my $index = 0; $index < @array; ++$index ) { }
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      只需将 shift @_ 更改为 $_ 即可解决此问题。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-28
        • 1970-01-01
        • 2019-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多