要在Perl中编写闭包,我们需要编写
sub test {
my( $x, $y, $z ) = @_;
my $closure = sub{ $x + $y + $z };
}
但有时,如果不是总是,子程序可能有很多行,我想把子程序的定义放在外面并使用类似的东西
my $z;
sub test {
my( $x, $y ) = @_;
my $closure = closure( 'subname', $x, $y, $z );
}
sub subname : closure ( $var1, $var2, $var3 ) {
$var1 + $var2 + $var3
}
所以我可以从其他地方重用这个闭包
my $on2;
sub test_xxx {
my( $other_name1, $on3 ) = @_;
my $closure = closure( 'subname', $on3, $other_name1, $on2 );
}
这在Perl中是否可行?
答案 0 :(得分:4)
closure
定义如下:
sub closure {
my ($sub_name, @args) = @_;
my $sub = \&$subname;
return sub { $sub->(@args) };
}
但是这种间接是没有用的。相反,只需替换
my $closure = closure( 'subname', $x, $y, $z );
my $closure = closure( 'subname', $on3, $other_name1, $on2 );
与
my $closure = sub { subname($x, $y, $z) };
my $closure = sub { subname($on3, $other_name1, $on2) };
如果你确实需要助手,那就不那么通用了。它通常会有一些特定于任务的准备代码,后跟return sub { };
sub make_foo_iter {
my @args = @_;
# ...
return sub {
# ...
};
}
my $iter = make_foo_iter(...);
答案 1 :(得分:3)
尝试这样的事情:
use 5.012;
use warnings;
my $z;
sub test
{
my ($x, $y) = @_;
return sub { complicated_code($x, $y, $z) };
}
my $on2;
sub test_xxx
{
my ($other_name1, $on3) = @_;
return sub { complicated_code($on3, $other_name1, $on2) };
}
sub complicated_code
{
my ($a, $b, $c) = @_;
return $a + $b + $c;
}
$z = 42;
my $closure = test(2,3);
say $closure->(); # 47
$z = 1;
say $closure->(); # 6
my $closure_xxx = test_xxx(4,5);
$on2 = 23;
say $closure_xxx->(); # 32
换句话说,在常规sub
中添加许多行的复杂代码,只需在闭包中调用此sub
。