coderefs中的变量范围如果是perl,需要解释奇怪的行为

时间:2015-01-07 11:42:07

标签: perl variables scope

为什么@coderefs中的coderefs返回的$ copy_of_i的值相同?

use Modern::Perl;
my @coderefs = ();
for (my $i = 0; $i < 5; $i++){
    push @coderefs, sub { 
        my $copy_of_i = $i;
        return $copy_of_i;
    };
}

say $coderefs[1]->();
say $coderefs[3]->();

我认为$ copy_of_i对于添加到@coderefs的每个coderef都是本地的,因此包含在循环的给定迭代中分配给$ copy_of_i的$ i的当前值。但是如果我们用'say'显示几个$ copi_of_i的值,我们会看到它们具有相同的值,就好像每个新创建的coderef的$ copy_of_i不是本地的一样。为什么呢?

1 个答案:

答案 0 :(得分:4)

您希望将不同的值与闭包相关联,但是您只能获取要捕获的所有闭包的单个变量$i。您需要为每个要捕获的闭包创建一个变量,因此应该在闭包之外创建$copy_of_i。你打电话给关闭时创建副本已经太晚了; $i此时不再包含所需的值。

for (my $i = 0; $i < 5; $i++){
    my $copy_of_i = $i;
    push @coderefs, sub { 
      return $copy_of_i;
    };
}

顺便说一下,for my $i (0 .. 5)for (my $i = 0; $i < 5; $i++)更受欢迎,并且它具有为循环的每次迭代创建一个新变量的优势,因此您只需使用

my @coderefs;
for my $i (0 .. 4) {
    push @coderefs, sub { 
      return $i;
    };
}