为什么@coderefs中的coderef返回的$ 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的值,我们将看到它们具有相同的值,就好像$ copy_of_i不是每个新创建的coderef的本地值一样。为什么?

最佳答案

您希望具有与闭包关联的不同值,但是对于所有要捕获的闭包,您只有一个变量$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;
    };
}

10-08 11:01