3 回答
TA贡献1993条经验 获得超5个赞
IMO,唯一有理由使用的时间&是,如果您正在获取或调用代码引用,例如:
sub foo() {
print "hi\n";
}
my $x = \&foo;
&$x();
主要的时间,你可以,你使用它绝对不应该在大多数情况下,调用一个已具雏形,指定任何非默认调用行为子时。我的意思是,某些原型允许重新解释参数列表,例如将引用转换@array和指定%hash为引用。因此,潜艇将期望发生这些重新解释,并且除非您进行任何必要的长度以手工模拟它们,否则潜艇将获得与预期的输入完全不同的输入。
我认为主要是人们试图告诉您您仍在以Perl 4风格进行编写,而我们现在有了一个更干净,更好的东西,称为Perl 5。
关于性能,Perl有多种方法可以优化&失败的子调用,其中一种主要方法是常量的内联。
在某些情况下,使用&可以带来性能上的好处:如果您要转发带有的子呼叫foo(@_)。使用&foo比无限快foo(@_)。除非您通过分析明确确定需要微优化,否则我不建议您这样做。
TA贡献1810条经验 获得超4个赞
我经常滥用&,但是主要是因为我在做怪异的界面设计。如果您不需要这些情况之一,请不要使用&。其中大多数只是访问子例程定义,而不是调用子例程。全部都在perlsub中。
引用命名子例程。对于大多数Perlers来说,这可能是唯一的常见情况:
my $sub = \&foo;
类似地,分配给typeglob,这使您可以使用不同的名称调用子例程:
*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 }
}
要使用当前参数堆栈跳入另一个子例程(并替换调用堆栈中的当前子例程),则在分配过程中会执行一个稀疏操作,尤其是在AUTOLOAD:
goto ⊂
调用以Perl内置函数命名的子例程。将&始终为您提供了用户定义的。这就是为什么我们在Learning Perl中教它。您实际上并不是真的想正常执行此操作,但这是的功能之一&。
在某些地方可以使用它们,但是有更好的方法:
调用与Perl内置名称相同的子例程。只是没有与Perl内置名称相同的子例程。检查perlfunc以查看不应该使用的内置名称列表。
禁用原型。如果您不知道这意味着什么或为什么想要它,请不要使用&。一些黑魔法代码可能需要它,但是在这种情况下,您可能知道自己在做什么。
取消引用并执行子例程引用。只需使用->符号即可。
添加回答
举报