【发布时间】:2013-06-07 00:38:06
【问题描述】:
这里又是 Perl 新手,试图理解 Perl 中的closure。
所以这里有一个我不明白的代码示例:
sub make_saying {
my $salute = shift;
my $newfunc = sub {
my $target = shift;
print "$salute, $target!\n";
};
return $newfunc; # Return a closure
}
$f = make_saying("Howdy"); # Create a closure
$g = make_saying("Greetings"); # Create another closure
# Time passes...
$f->("world");
$g->("earthlings");
所以我的问题是:
- 如果将变量分配给函数,它是否会自动引用该函数?
- 在上面的代码中,我可以改写
$f = \make_saying("Howdy")吗?我什么时候可以使用&,因为我尝试在传递参数时使用它(&$f("world")),但它不起作用。 - 最后,在上面的代码中,他**如何将单词
world和earthlings附加到单词howdy和greetings之后。
注意:我知道 $f 在某种程度上绑定到带有参数 howdy 的函数,所以这就是我理解 world 是如何附加的。我不明白的是里面的第二个功能。那个人如何发挥它的魔力。对不起,我真的不知道怎么问这个。
【问题讨论】:
-
+1 问题写得很好。我希望这里有一些有见地的答案:)
-
"# 返回一个闭包"。这是一个常见的误解,反映在(词汇)“闭包”的许多定义中。外部函数实际上返回一个(对 a 的引用)function。这样就形成了一个闭包。
-
@Beetroot-Beetroot 我猜原因是闭包必然随函数一起携带,因此在某种意义上与函数一起“返回”。或者这也不符合您在这里暗示的“关闭”的定义? (真的很想了解这种区别。)
-
@IMSoP 如果准确地说,
my $x = 5; return sub { 1 + $_[0]}和my $x = 5; my $f = sub { $x + $_[0] }; $f->(37);都没有使用闭包:在第一个示例中,该函数不引用外部范围内的任何变量。第二个示例在定义它的相同环境中使用该函数。在实践中,最好将闭包视为函数-指针 × 环境对。调用闭包时,重新安装环境,然后运行该函数。退出时,环境被卸载,调用者环境重新进入。 -
@amon 我不确定我是否遵循这两个示例:在第一种情况下,我可以看到编译器可能会发现不需要环境中的任何内容,然后将其丢弃;第二,在实践中永远不需要重新安装环境。但在这两种情况下,至少在概念上都需要捕获,以便语言支持闭包。否则,一个通过捕获的环境传递但从未执行的函数也不会是一个闭包,这似乎是一个不切实际的定义。