9

それで、私はこれを知りませんでした、そして、私はそれについていくらかの説明を得たいです。私はあなたがそうするかどうか知っています

foreach (@list){

そのループで$_を変更すると、実際のデータに影響します。しかし、あなたがそうしたら私はそれを知りませんでした

foreach my $var1 (@list){

ループで$var1を変更すると、実際のデータが変更されます。:-/では、@ listをループするが、変数を読み取り専用コピーのままにする方法、または変更しても@listの値が変更されないコピーはありますか?

4

6 に答える 6

10

$var順番に各アイテムにエイリアスされます。

http://perldoc.perl.org/perlsyn.html#Foreach-Loopsを参照してください

LISTのいずれかの要素が左辺値である場合、ループ内のVARを変更することでそれを変更できます。逆に、LISTのいずれかの要素が左辺値でない場合、その要素を変更しようとすると失敗します。つまり、foreachループインデックス変数は、ループしているリスト内の各アイテムの暗黙的なエイリアスです。

于 2009-06-18T15:22:25.363 に答える
9

最も簡単な方法は、それをコピーすることです。

foreach my $var1 (@list) {
    my $var1_scratch = $var1;

また

foreach my $var1 ( map $_, @list ) {

ただし、$ var1が参照である場合、$var1_scratchは同じものへの参照になります。本当に安全にするには、Storable::dcloneのようなものを使用してディープコピーを実行する必要があります。

foreach my $var1 ( @{ Storable::dclone( \@list ) } ) {
}

(未テスト)。そうすれば、$var1を安全に変更できるはずです。ただし、@ listが大きなデータ構造である場合は、コストがかかる可能性があります。

于 2009-06-18T15:21:45.143 に答える
4

これはエイリアスであり、参照ではありません。独自のエイリアス(for以外)を作成する場合は、 Data::Aliasを使用できます。

于 2009-06-18T15:51:46.607 に答える
2

これらのループの唯一の違いは次のとおりです。

foreach (@array) { ... }
foreach my $var (@array) { ... }

ループ変数です。エイリアシングはの関数でforeachあり、暗黙の変数ではありません$_。これはエイリアス(同じものの別名)であり、参照(物へのポインタ)ではないことに注意してください。

単純な(そして一般的な)ケースでは、コピーを作成することでエイリアシングを破ることができます。

foreach my $var (@array) {
    my $copy = $var;
    # do something that changes $copy
}

これは通常のスカラー値に対して機能します。参照(またはオブジェクト)の場合、 StorableまたはCloneを使用してディープコピーを作成する必要がありますが、これはコストがかかる可能性があります。関連付けられた変数にも問題があります。perlsynは、この状況を完全に回避することをお勧めします。

于 2009-06-18T16:26:50.497 に答える
1

foreachステートメント自体で変数を参照ではなく値で強制する方法がわかりません。ただし、の値をコピーできます$_

#!/usr/perl/bin
use warnings;
use strict;

use Data::Dumper;

my @data = (1, 2, 3, 4);

print "Before:\n", Dumper(\@data), "\n\n\n";

foreach (@data) {
    my $v = $_;
    $v++;
}

print "After:\n", Dumper(\@data), "\n\n\n";

__END__
于 2009-06-18T15:22:55.423 に答える
1

forステートメントに@listのコピーを作成します。

foreach my $var1 (() = @list) {
  # modify $var without modifying @list here
}
于 2011-09-10T04:23:00.273 に答える