为了账号安全,请及时绑定邮箱和手机立即绑定

什么时候应该使用&调用Perl子例程?

什么时候应该使用&调用Perl子例程?

我听说人们不应该&习惯于调用Perl潜艇,即:function($a,$b,...);# opposed to&function($a,$b,...);我知道其中一个参数列表是可选的,但是在什么情况下适合使用&和哪些情况下您绝对不应该使用它呢?另外,省略时如何提高性能&呢?
查看完整描述

3 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

IMO,唯一有理由使用的时间&是,如果您正在获取或调用代码引用,例如:


sub foo() {

    print "hi\n";

}


my $x = \&foo;

&$x();

主要的时间,你可以,你使用它绝对不应该在大多数情况下,调用一个已具雏形,指定任何非默认调用行为子时。我的意思是,某些原型允许重新解释参数列表,例如将引用转换@array和指定%hash为引用。因此,潜艇将期望发生这些重新解释,并且除非您进行任何必要的长度以手工模拟它们,否则潜艇将获得与预期的输入完全不同的输入。


我认为主要是人们试图告诉您您仍在以Perl 4风格进行编写,而我们现在有了一个更干净,更好的东西,称为Perl 5。


关于性能,Perl有多种方法可以优化&失败的子调用,其中一种主要方法是常量的内联。


在某些情况下,使用&可以带来性能上的好处:如果您要转发带有的子呼叫foo(@_)。使用&foo比无限快foo(@_)。除非您通过分析明确确定需要微优化,否则我不建议您这样做。


查看完整回答
反对 回复 2019-10-28
?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

我经常滥用&,但是主要是因为我在做怪异的界面设计。如果您不需要这些情况之一,请不要使用&。其中大多数只是访问子例程定义,而不是调用子例程。全部都在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以查看不应该使用的内置名称列表。


禁用原型。如果您不知道这意味着什么或为什么想要它,请不要使用&。一些黑魔法代码可能需要它,但是在这种情况下,您可能知道自己在做什么。


取消引用并执行子例程引用。只需使用->符号即可。


查看完整回答
反对 回复 2019-10-28
  • 3 回答
  • 0 关注
  • 492 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信