我使用 Perl 已经有一段时间了,但是今天我遇到了这段代码:
sub function1($$)
{
//snip
}
这在 Perl 中意味着什么?
我使用 Perl 已经有一段时间了,但是今天我遇到了这段代码:
sub function1($$)
{
//snip
}
这在 Perl 中意味着什么?
它是一个带有带有两个标量参数的原型的函数。
通常不实际使用 Perl 原型有很强的论据 - 正如下面的评论中所指出的。最有力的论据可能是:
从 2008 年开始有关于 StackOverflow 的讨论:
MooseX::Method::Signatures模块中有一个可能的替代品。
正如另一个答案所提到的,$$
声明了一个原型。另一个答案没有说的是原型的用途。它们不是用于输入验证,它们是解析器的提示。
想象一下,您有两个函数声明如下:
sub foo($) { ... }
sub bar($$) { ... }
现在当你写一些模棱两可的东西时,比如:
foo bar 1, 2
Perl 知道把括号放在哪里;bar 需要两个参数,因此它消耗最接近它的两个参数。foo 需要一个 arg,所以它需要 bar 和两个 args 的结果:
foo(bar(1,2))
另一个例子:
bar foo 2, 3
这同样适用;foo 需要一个 arg,所以它得到 2。 bar 需要两个 arg,所以它得到foo(2)
3:
bar(foo(2),3)
这是 Perl 的一个非常重要的部分,因此将其视为“从不使用”是对您的伤害。几乎每个内部函数都使用原型,因此通过了解它们在您自己的代码中的工作方式,您可以更好地了解内置函数如何使用它们。然后你可以避免不必要的括号,这使得代码看起来更愉快。
最后,我会警告你一种反模式:
package Class;
sub new ($$) { bless $_[1] }
sub method ($) { $_[0]->{whatever} }
当您将代码作为方法(Class->method
或$instance->method
)调用时,原型检查完全没有意义。如果你的代码只能作为方法调用,添加原型是错误的。我见过一些流行的模块可以做到这一点(你好,XML::Compile
),但这是错误的,所以不要这样做。如果您想记录要传递多少个参数,如何:
sub foo {
my ($self, $a, $b) = @_; # $a and $b are the bars to fooify
....
或者
use MooseX::Method::Signatures;
method foo(Bar $a, Bar $b) { # fooify the bars
....
与 不同foo($$)
的是,这些是有意义且可读的。