foreach my $ var(@list)— $ varは参照ですか?
質問
だから、私はこれを知らなかったので、それについて明確にしたいと思います。知っているかどうか
foreach (@list){
そのループで$ _を変更すると、実際のデータに影響します。しかし、もしあなたがそうしたら
foreach my $var1 (@list){
ループで$ var1を変更すると、実際のデータが変更されます。 :-/それでは、@ listをループする方法はありますが、変数を読み取り専用コピー、または変更しても@listの値を変更しないコピーを保持する方法はありますか?
解決
$ var
は各アイテムに順番にエイリアスされます。
http://perldoc.perl.org/perlsyn.html#Foreach-Loopsを参照
LISTのいずれかの要素が左辺値である場合、ループ内でVARを変更することにより、それを変更できます。 逆に、LISTの要素が左辺値でない場合、その要素を変更しようとすると 失敗します。つまり、foreachループインデックス変数は、それぞれの暗黙的なエイリアスです。 ループしているリスト内のアイテム。
他のヒント
最も簡単な方法は、コピーすることです:
foreach my $var1 (@list) {
my $var1_scratch = $var1;
または
foreach my $var1 ( map 最も簡単な方法は、コピーすることです:
foreach my $var1 (@list) {
my $var1_scratch = $var1;
または
foreach my $var1 ( @{ Storable::dclone( \@list ) } ) {
}
ただし、$ var1が参照の場合、$ var1_scratchは同じものへの参照になります。
本当に安全にするには、Storable :: dcloneのようなものを使用してディープコピーを行う必要があります:
<*>
(未テスト)。そうすれば、$ var1を安全に変更できるはずです。しかし、それは高価な場合があります
@listは大きなデータ構造です。
, @list ) {
ただし、$ var1が参照の場合、$ var1_scratchは同じものへの参照になります。 本当に安全にするには、Storable :: dcloneのようなものを使用してディープコピーを行う必要があります:
<*>(未テスト)。そうすれば、$ var1を安全に変更できるはずです。しかし、それは高価な場合があります @listは大きなデータ構造です。
これはエイリアスであり、参照ではありません。 (forの外で)独自のエイリアスを作成する場合は、 Data :: Alias 。
これらのループの唯一の違い:
foreach (@array) { ... }
foreach my $var (@array) { ... }
はループ変数です。エイリアシングは、暗黙的な変数 $ _
ではなく、 foreach
の関数です。これはエイリアス(同じものの別名)であり、参照(ものへのポインター)ではないことに注意してください。
単純な(そして一般的な)場合、コピーを作成することでエイリアスを解除できます:
foreach my $var (@array) {
my $copy = $var;
# do something that changes $copy
}
これは通常のスカラー値に対して機能します。参照(またはオブジェクト)の場合、 Storable またはクローン。これは高価になる可能性があります。関連付けられた変数にも問題があります。 perlsyn は、このような状況を完全に回避することをお勧めします。
変数を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 = 変数をforeachステートメント自体の参照ではなく値ごとに強制する方法がわかりません。ただし、 $ _
の値をコピーできます。
<*>;
$v++;
}
print "After:\n", Dumper(\@data), "\n\n\n";
__END__
forステートメントで@listのコピーを作成します。
foreach my $var1 (() = @list) {
# modify $var without modifying @list here
}