我应在何时使用&;调用Perl子例程?
我听说人们不应该使用我应在何时使用&;调用Perl子例程?,perl,subroutine,Perl,Subroutine,我听说人们不应该使用&来调用Perl subs,即: function($a,$b,...); # opposed to &function($a,$b,...); 我知道参数列表是可选的,但是在哪些情况下使用&是合适的,哪些情况下绝对不应该使用它 此外,当省略&时,性能增加是如何发挥作用的?在我看来,唯一有理由使用&的时间是在您获取或调用coderef时,例如: sub foo() { print "hi\n"; } my $x = \&foo; &$x()
&
来调用Perl subs,即:
function($a,$b,...);
# opposed to
&function($a,$b,...);
我知道参数列表是可选的,但是在哪些情况下使用&
是合适的,哪些情况下绝对不应该使用它
此外,当省略
&
时,性能增加是如何发挥作用的?在我看来,唯一有理由使用&
的时间是在您获取或调用coderef时,例如:
sub foo() {
print "hi\n";
}
my $x = \&foo;
&$x();
在大多数情况下,您可以使用它(绝对不应该)的主要时间是在调用具有指定任何非默认调用行为的原型的sub时。我的意思是,一些原型允许重新解释参数列表,例如将@array
和%hash
规范转换为引用。因此,sub将期望这些重新解释已经发生,除非你用手去模仿它们,否则sub将得到与预期完全不同的输入
我想人们主要是想告诉你,你仍然在用Perl4风格写作,现在我们有了一个更干净、更好的东西,叫做Perl5
关于性能,Perl优化子调用的方法有多种,&
会失败,其中一种主要方法是常量内联
还有一种情况下,使用&
可以提高性能:如果您使用foo(@41;
转发子呼叫。使用&foo
比foo(@)
快无穷多。我不推荐它,除非您通过分析最终发现您需要这种微优化。subroutine()表单禁用原型检查。这可能不是你想要的
原型允许您指定子例程参数的数量和类型,并在编译时检查它们。这可以提供有用的诊断帮助
原型不适用于方法调用,也不适用于使用&prefix的老式样式的调用
&是引用或取消引用子例程或代码引用所必需的
e、 g
Protypes也不适用于子例程引用
&subroutine形式也用于所谓的形式
表达式goto&subroutine
将当前调用上下文替换为使用@的当前值调用指定的子例程
本质上,您可以通过调用指定的子例程来完全切换对一个子例程的调用。这在自动加载块中很常见,在自动加载块中可以进行延迟子例程调用,可能需要对@进行一些修改,但在程序看来,它完全像是对指定子例程的调用
e、 g
}
我想,这可能会对你有用
请看我经常滥用
&
,但主要是因为我在做一些奇怪的界面工作。如果您不需要这些情况之一,请不要使用&
。其中大多数只是访问子例程定义,而不是调用子例程。都在里面
my $sub = \&foo;
*bar = \&foo;
if( defined &foo ) { ... }
undef &foo;
&
调用子例程的唯一情况,当我希望多次调用调度程序并需要从操作中挤出一点性能时:
sub figure_it_out_for_me {
# all of these re-use the current @_
if( ...some condition... ) { &foo }
elsif( ...some other... ) { &bar }
else { &default }
}
自动加载中:
goto ⊂
&
始终提供用户定义的代码。那是。您并不想正常地这样做,但这是&
的功能之一&
。一些黑魔法代码可能需要它,但在这些情况下,您可能知道自己在做什么->
符号即可我读过反对使用“&”的论点,但我几乎总是使用它。这节省了我太多的时间。我花了大量Perl编码时间寻找代码中调用特定函数的部分。使用前导&,我可以立即搜索并找到它们。如果没有前导&,我会得到函数定义、注释和调试语句,通常需要检查三倍的代码才能找到所需的内容
不使用“&”的主要原因是它允许您使用函数原型。但是Perl函数原型可能会创建错误,因为它们会以您可能不期望的方式重新解释您的参数列表,从而使您的函数调用不再传递它字面上所说的参数。您能详细介绍一下“非默认调用行为”部分吗?除了,
和$x之外()
并不是调用代码引用的最佳方式;您可能应该像其他任何引用一样取消引用它:$x->()
sub figure_it_out_for_me {
# all of these re-use the current @_
if( ...some condition... ) { &foo }
elsif( ...some other... ) { &bar }
else { &default }
}
goto ⊂