将args传递给递归函数还是让动态范围处理它更好?
sub rec {
my ($arg1, $arg2 ..) = (@_);
..
rec(..);
}
或者更确切地说:
sub main {
our ($arg1, $arg2 ..) = (@_);
sub rec {
my $arg1 = shift;
.. # use $args > 1
rec($arg1);
}
由于我在main中有几个rec subs,我更喜欢第二个选项,它不需要一直传递vars并减少数量膨胀的代码。说它可能效率不高,因为它会通过每个堆栈帧来解决动态范围?
答案 0 :(得分:2)
不要将命名子例程放在另一个子例程中。这会导致问题(虽然use warnings;
会找到它们)。如果你想避免将常量参数传递给每个递归,我建议改为:
sub recurse {
my ($constant, ...) = @_;
local *_recurse = sub {
my (...) = @_;
...
_recurse(...);
...
};
_recurse(...);
}
(不知道您使用our
的原因。我转回my
。)
或者使用足够新版本的Perl(5.16 +):
sub recurse {
my ($constant, ...) = @_;
my $_recurse = sub {
my (...) = @_;
...
__SUB__->(...);
...
};
$_recurse->(...);
}
无论你做什么,都不要做以下事情,因为它泄漏了。
sub recurse {
...
my $_recurse;
$_recurse = sub {
...
$_recurse->(...);
...
};
...
}
(内部子引用$_recurse
,它包含对内部子的引用,形成一个引用循环,从而形成内存泄漏。)
答案 1 :(得分:0)
如果您正在使用依赖于全局变量的递归函数,则几乎可以肯定将其重新编码为使用本地范围变量的迭代子例程。
我强烈建议您始终传递变量并返回值,并重新考虑算法的设计以使用迭代(while
循环)与递归。
如果您为方法添加详细信息,我们可能会建议实际实施。但鉴于您分享的信息量,我们所能做的只是建议设计理论。