我应该调用没有参数的Perl子例程作为marine()或marine吗?

Nan*_* HE 14 perl subroutine

根据我下面的示例代码,调用子例程有两种样式:subnamesubname().

#!C:\Perl\bin\perl.exe
use strict;
use warnings;

use 5.010;

&marine(); # style 1
&marine; # style 2

sub marine {
    state $n = 0; # private, persistent variable $n
    $n += 1;
    print "Hello, sailor number $n!\n";
}
Run Code Online (Sandbox Code Playgroud)

如果呼叫中没有参数,哪一个&marine();或哪个&marine;是更好的选择?

bri*_*foy 23

Learning Perl中,这个例子来自于我们,我们正在向您展示子例程.我们只告诉你使用它,&以便你作为开始Perler,不会遇到一个问题,你定义一个与内置Perl同名的子程序然后想知道为什么它不起作用.在&前面总是调用您定义的子程序.初学者经常创建自己的子程序log来打印消息,因为他们习惯于在他们使用的其他技术中这样做.在Perl中,这是内置的数学函数.

在您习惯使用Perl并且了解Perl内置函数(扫描perlfunc)之后,请删除&.&你几乎不需要一些特殊的魔力:

 marine();
Run Code Online (Sandbox Code Playgroud)

()如果你已经预先声明了子程序,你可以不用它,但我通常会在()那里留下一个空的参数列表.由于你给Perl提供了marine一个子程序名称的提示,因此它更加健壮.对我而言,我更快地认识到它是一个子程序.

  • 你也给自己和代码的其他维护者暗示它是一个子程序名称. (7认同)
  • 也许在示例中放弃使用"&"可能是最好的,因为它可能会被不适当地使用. (5认同)

mob*_*mob 15

&没有括号使用的副作用是调用子程序@_.这个计划

sub g {
  print "g: @_\n";
}
sub f {
  &g();   # g()
  &g;     # g(@_)
  g();    # g()
  g;      # g()
}
f(1,2,3);
Run Code Online (Sandbox Code Playgroud)

产生这个输出:

g:
g: 1 2 3
g:
g:

  • @Dave,`&subname;`如果你偶然发现它就是邪恶的.但也可能有用.假设您有40或50个具有类似参数清理需求的子例程.您可以创建一个直接在调用函数的arg列表上运行的清理程序.`sub foo {&clean_args; 我的$ foo = shift; }}``是的,你可以在函数中返回一个单独的数组并处理它,但是你必须在各处修改你的参数处理语法.这些"恐怖"使用得很少,并且适当地使得可以轻松地完成困难的事情. (4认同)
  • 就像我爱Perl一样,似乎没有一个星期过去没有我知道隐藏在那里等待咬我的新恐怖. (3认同)

dax*_*xim 7

使用sub关键字首先声明子例程然后调用它们是一种很好的方式.(当然有很多方法,但为什么要让事情变得更复杂?)

不要使用&语法,除非你知道它的作用@_和用原型声明的子程序.它非常模糊,很少需要,并且是通过意外行为造成的错误来源.离开它 - Perl :: Critic恰如其分地说:

从Perl 5开始,在调用子程序时,&符号是完全可选的.

现在,根据这些样式提示,我更喜欢调用不需要样式1中的参数的子例程,也就是说marine();.原因是

  1. 与需要参数的子程序的视觉一致性
  2. 它不能与不同的关键字混淆.