perl闭包和$ _

dav*_*k01 16 perl closures programming-languages

我尝试用不熟悉的编程语言学习的第一件事就是它如何处理闭包.它们的语义通常与语言如何处理范围和各种其他棘手的部分交织在一起,因此理解它们会揭示该语言的其他几个方面.此外,闭合是一个非常强大的构造,并且通常会减少我必须键入的样板量.所以我正在搞乱perl闭包,我偶然发现了一个小问题:

my @closures;
foreach (1..3) {
  # create some closures
  push @closures, sub { say "I will remember $_"; };
}
foreach (@closures) {
  # call the closures to see what they remember
  # the result is not obvious
  &{$_}();
}
Run Code Online (Sandbox Code Playgroud)

当我编写上述代码时,我期待看到

I will remember 1
I will remember 2
I will remember 3
Run Code Online (Sandbox Code Playgroud)

但相反,我得到了I will remember CODE(0x986c1f0).

上面的实验揭示了它$_是非常依赖于上下文的,如果它出现在一个闭包中,那么它的值不会在闭包创建时固定.它的行为更像是一个参考.在perl中创建闭包时,我应该注意哪些其他问题?

yst*_*sth 24

闭包只关闭词法变量; $_通常是一个全局变量.在5.10及以上版本中,您可以说它my $_;在给定范围内具有词汇性(尽管在5.18中,这被追溯性地声明为实验性的并且可能会发生变化,因此最好使用其他变量名称).

这会产生您期望的输出:

use strict;
use warnings;
use 5.010;
my @closures;
foreach my $_ (1..3) {
  # create some closures
  push @closures, sub { say "I will remember $_"; };
}
foreach (@closures) {
  # call the closures to see what they remember
  # the result is not obvious
  &{$_}();
}
Run Code Online (Sandbox Code Playgroud)

  • 但这与使用`foreach my $ num ...`几乎相同. (2认同)