Programmingフルスタック開発者

Perlのforeachループについて説明してください: 配列の要素のコピーとオリジナルでの作業の違いは何ですか? ループ変数を使用する際の罠は何ですか?

Hintsage AIアシスタントで面接を突破

答え

Perlでは、foreachループを使用すると、配列の要素を便利に繰り返すことができ、ループ変数はデフォルトで($_、または明示的に指定された)参照として配列の要素を指すため、値をコピーしません。

例:

my @arr = (1, 2, 3); foreach my $x (@arr) { $x *= 2; } # @arrは(2, 4, 6)となる — 要素が変更されました!

値のコピーを取得するには(オリジナルの要素への参照ではなく)、変数に明示的に代入する必要があります:

foreach my $x ( @arr ) { # $xは要素への参照 ... } # ↓↓↓↓ foreach (@arr) { my $copy = $_; ... } # $copyはコピー、$_は要素への参照

複数の入れ子のforeachループで同じ変数を使用しない方が良いでしょう。そうしないと、予期しない副作用が発生する可能性があります。


トリックのある質問

foreachループの変数は独立したコピーであり、ループ本体の中で安全に変更できますか?

一般的に "はい、ループは自動的に変数を作成するので、自由に変更できます。" と答えます。

正しい答え:

Perlでは、デフォルトのループ変数(例えば、foreach $var (@arr))は、配列の要素への**エイリアス(参照)**です。ループ変数を変更すると、オリジナルの要素も変更されます!

一時的なコピーを変更するには、ループの内部で明示的に代入してください:

foreach my $elem (@arr) { my $t = $elem; $t++; # コピーだけで、オリジナルの配列は変更されません }

歴史


歴史 1

レコードをフィルタリングするタスクで、プログラマーはループ変数を変更したが、オリジナルのデータを変更していることに気付いていませんでした。その結果、次の計算は変更された配列に従って行われ、要素の合計が正しく計算されませんでした。このエラーは、リファレンスサンプルと比較したときにのみ発生しました。


歴史 2

内部のforeachで同じ変数($item)を使用しました。内部ループの変数が外部の状態を上書きし、最初の走行の結果が失われ、配列の一部が不正な値になりました。


歴史 3

ハッシュへの参照の配列をforeachで繰り返し、それぞれのループでループ変数に新しい値が割り当てられました。その結果、参照が「壊れ」、参照値の代わりにスカラーが配置され、次の処理ステージが型エラーで失敗しました。