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?への引数のうち 3 つだけを出力します。

同じように動作するように見えるこの関数が、5 つの引数すべてを処理するのはなぜですか?

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

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

これも5つすべてを読み取ります(ただし、異なる原則で動作します):

my @arr=();

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

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

4 に答える 4

6

foreach同じアレイでとを使用すると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 @_内部foreach (@_)が間違っているので、それを取り除くと配列ウォークが修正されます。

$ 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 に答える