在尝试理解闭包时,在perl-faq中通过perlref和coderef
阅读了这些示例:
sub add_function_generator {
return sub { shift() + shift() };
}
my $add_sub = add_function_generator();
my $sum = $add_sub->(4,5);
和
sub newprint {
my $x = shift;
return sub { my $y = shift; print "$x, $y!\n"; };
}
$h = newprint("Howdy");
&$h("world");
这里有两种调用存储在变量中的函数的形式。
&$func($arg)
$func->($arg)
那些是完全等效的(只是语法上不同)还是存在一些差异?
答案 0 :(得分:13)
没有区别。证明:每个版本生成的操作码:
$ perl -MO=Concise -e'my $func; $func->()'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
3 <0> padsv[$func:1,2] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v:{ ->5
7 <1> entersub[t2] vKS/TARG ->8
- <1> ex-list K ->7
5 <0> pushmark s ->6
- <1> ex-rv2cv K ->-
6 <0> padsv[$func:1,2] s ->7
$ perl -MO=Concise -e'my $func; &$func()'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
3 <0> padsv[$func:1,2] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v:{ ->5
7 <1> entersub[t2] vKS/TARG ->8
- <1> ex-list K ->7
5 <0> pushmark s ->6
- <1> ex-rv2cv sKPRMS/4 ->-
6 <0> padsv[$func:1,2] s ->7
...等等,- <1> ex-rv2cv sKPRMS/4 ->-
的标志实际上略有不同。无论如何,它们似乎并不重要,两种形式都表现相同。
但我建议使用$func->()
形式:我认为这种语法更优雅,你不会忘记使用parens(&$func
有效,但会使当前{{1}对函数可见,这不是你通常想要的。)