4

次のコードでは、エラー メッセージが表示されます。

#!/usr/bin/perl -w

foreach my $var (0, 1, 2){
    $var += 2;
    print "$var\n";
}

Modification of a read-only value attempted at test.pl line 4.

変更する方法はあります$varか? (好奇心から聞いただけです。実際にこのエラー メッセージを見て非常に驚きました。)

4

3 に答える 3

12

foreach $var (@list)構文では、 のメモリ アドレスがの要素と同じアドレスになる$varという意味で、 はループの要素にエイリアスされます。そのため、サンプル コードは読み取り専用の値を変更しようとすると、エラー メッセージが表示されます。$var@list

この小さなスクリプトは、foreachコンストラクトで何が起こっているかを示しています。

my @a = (0,1,2);
print "Before: @a\n";
foreach my $var (@a) {
  $var += 2;
}
print "After:  @a\n";

Before: 0 1 2
After:  2 3 4

追加情報: からのこのアイテムperlsynは簡単に見落としがちですが、スクープ全体を提供します:

Foreach ループ

...

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

于 2009-09-28T05:02:06.530 に答える
5

Perl は、ループ変数ではなく定数である値について不平を言っています。それが不平を言っている読み取り専用の値は、それに対するエイリアスであり、変数に保存されていない0ため$varです(これは変更できるものです)。配列または変数のリストをループする場合、その問題はありません。

于 2009-09-28T05:30:27.520 に答える
4

以下が同じメッセージにならない理由を理解することは、最初にメッセージが送信される理由の理解を深めるのに大いに役立ちます。

#!/usr/bin/perl

use strict;
use warnings;

for my $x ( @{[ 0, 1, 2 ]} ) {
    $x += 2;
    print $x, "\n";
}
于 2009-09-28T08:58:33.760 に答える