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 回答