我必须调试别人的代码并遇到看起来像这样的子声明......
sub mysub($$$$) {
<code here>
}
...还...
sub mysub($$$;$) {
<code here>
}
'$' 的括号列表(带有可选的';')是什么意思?
我进行了一个实验,它似乎并不关心我是否将越来越多的参数传递给以这种方式声明的子项,而不是列表中的“$”。我在想它可能被用来消除两个具有相同名称的不同潜艇的歧义,不同之处仅在于传递给它的参数数量(由 ($$$$) vs ($$$) vs ($$) 定义ETC... )。但似乎不是这样。
最佳答案
这是一个 Perl 子程序 prototype .这是一种让解析器知道需要多少参数的老式方法。除非您知道他们将为您做什么,否则我建议您在任何新代码中避免使用这些。如果您可以避免原型(prototype),请避免它。它并没有像你想象的那样让你受益。有一种更新但实验性的方法可以做得更好。;
之后的元素是可选参数。所以,mysub($$$$)
有四个强制参数,和 mysub($$$;$)
具有三个强制参数和一个可选参数。
一点关于解析
当你想指定参数时,Perl 让你对括号有点松散,所以这些是相同的:
print "Hello World";
print( "Hello World\n" );
这是 Perl 的哲学观点之一。当我们可以省略样板时,我们应该可以。
此外,Perl 允许您将任意数量的参数传递给子例程,并且您不必提前说明参数:
sub some_sub { ... }
some_sub( 1, 2, 3, 4 );
some_sub 1, 2, 3, 4; # same
这是 Perl 的另一个基本思想:我们有标量和列表。许多事情都在一个列表中起作用,我们不在乎它有什么或它有多少元素。
但是,一些内置函数需要一定数量的参数。
sin
只取一个参数(但 print
取零到有效无穷大):print sin 5, 'a'; # -0.958924274663138a (a is from `a`)
rand
取零或一:print rand; # 0.331390818188996
print rand 10; # 4.23956650382937
但是,您可以定义自己的子例程。原型(prototype)是一种模仿您在内置程序中看到的相同行为的方法(我认为这有点酷,但对生产情况也没有激励作用)。
我倾向于在参数列表中使用括号,因为我发现人们更容易看到我的意图(尽管并非总是使用
print
,我猜):print sin(5), 'a';
我喜欢原型(prototype)的一个有趣用途。您可以创建自己的语法,如
map
和 grep
block 形式:map { ... } @array;
如果您想玩弄它(但仍不让维护程序员接受它),请查看 Object::Iterate进行演示。
实验签名
Perl v5.20 引入了 experimental signatures feature您可以在其中为参数命名。所有这些都是必需的:
use v5.20;
use feature qw(signatures);
sub mysub ( $name, $address, $phone ) { ... }
如果你想要一个可选参数,你可以给它一个默认值:
sub mysub ( $name, $address, $phone = undef ) { ... }
由于这是一项实验性功能,因此每当您使用它时都会发出警告。您可以将其关闭:
no warnings qw(experimental::signatures);
关于perl - 在 perl 中, '$' 的括号列表在子声明中意味着什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58399823/