_fact前面的*的确切功能/用途是什么?如何等效地编写它?
sub fact {
my ($n) = @_;
local *_fact = sub {
my ($n, $prod) = @_;
return $prod if $n == 0;
return _fact($n-1, $n*$prod);
};
return _fact($n, 1);
}
fact($n);
最佳答案
理想情况下,该函数的作者希望使用
sub fact {
my ($n) = @_;
my $_fact; $_fact = sub {
my ($n, $prod) = @_;
return $prod if $n == 0;
return $_fact->($n-1, $n*$prod);
};
return $_fact->($n, 1);
}
不幸的是,这会导致内存泄漏。 anon子项具有对
$_fact
的引用,该引用包含对匿名子项的引用。需要清除$_fact
才能在退出时断开引用。sub fact {
my ($n) = @_;
my $_fact;
$_fact = sub {
my ($n, $prod) = @_;
return $prod if $n == 0;
return $_fact->($n-1, $n*$prod);
};
my $rv;
my $e = eval { $rv = $_fact->($n, 1); 1 } ? undef : ($@ || 'Unknown');
$_fact = undef;
die $e if $e
return $rv;
}
但这太丑了!避免该问题的一种方法是使用Y combinator。避免此问题的更简单方法是将代码引用存储在包变量中,而不是词法变量中(因为subs仅捕获词法变量)。这就是您发布的代码的作用。请记住
*_fact = sub { ... };
基本上是的运行时版本
sub _fact { ... }
两者都将sub分配给符号
_fact
的CODE插槽。也就是说,5.16引入了更好的解决方案:
use feature qw( current_sub );
sub fact {
my ($n) = @_;
my $_fact = sub {
my ($n, $prod) = @_;
return $prod if $n == 0;
return __SUB__->($n-1, $n*$prod);
};
return $_fact->($n, 1);
}
关于perl - 嵌套子前面的神秘*,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19777251/