我不知道如何为子程序设置默认参数。这是我的考虑:
sub hello {
print @_ || "Hello world";
}
如果你只需要一个参数,那么这样做很好。如果你需要为多个参数设置默认值呢?
我原本打算这样做:
sub hello {
my $say = $_[0] || "Hello";
my $to = $_[1] || "World!";
print "$say $to";
}
但那是很多工作... 必须有更简单的方法;可能是最佳实践吗?
我不知道如何为子程序设置默认参数。这是我的考虑:
sub hello {
print @_ || "Hello world";
}
如果你只需要一个参数,那么这样做很好。如果你需要为多个参数设置默认值呢?
我原本打算这样做:
sub hello {
my $say = $_[0] || "Hello";
my $to = $_[1] || "World!";
print "$say $to";
}
但那是很多工作... 必须有更简单的方法;可能是最佳实践吗?
我使用命名参数来完成它,像这样:
sub hello {
my (%arg) = (
'foo' => 'default_foo',
'bar' => 'default_bar',
@_
);
}
我相信Params::Validate支持默认值,但那比我想要承担的麻烦更多。
通常我会做类似于以下的操作:
sub hello {
my ($say,$to) = @_;
$say ||= "Hello";
$to ||= "World!";
print "$say $to\n";
}
请注意,从 Perl 5.10 开始,您可以使用 "//=
" 运算符来测试变量是否已定义,而不仅仅是非零。(想象一下调用 hello("0","friend")
,使用上述内容将产生 "Hello friend"
,这可能不是您想要的结果。使用 //=
运算符将产生 "0 friend"
)。
Method::Signatures
。它使用Devel::Declare
提供了一些额外的(必要的!)语法糖,关键字为method
和func
。
下面是使用新的func
的示例:
use Method::Signatures;
func hello ($say='Hello', $to='World!') {
say "$say $to";
}
hello( 'Hello', 'you!' ); # => "Hello you!"
hello( 'Yo' ); # => "Yo World!"
hello(); # => "Hello World!"
/I3az/
#!/usr/bin/perl
use strict;
use warning;
my %myhash = (say => "Hello", to => "Stack Overflow");
sub hello {
my ($say, $to) = @_;
$say = $say ? $say : $myhash{say};
$to = $to ? $to : $myhash{to};
print "$say $to\n";
}
hello('Perl'); # output :Perl Stack Overflow
hello('','SO'); # output :Hello SO
hello('Perl','SO'); # output :Perl SO
hello(); # output :Hello Stack Overflow
如需更多详情和完整示例,请参考Perl最佳实践。
我最喜欢的方法是:自Perl 5.10版本以来,您可以使用//
检查变量是否已定义,并在未定义时提供替代值。因此,一个简单的示例是:
my $DEFAULT_VALUE = 42;
sub f {
my ($p1, $p2) = @_;
$p1 //= 'DEFAULT';
$p2 // = $DEFAULT_VALUE;
}
shift
指令从@_
中获取参数:sub f {
my $p1 = shift // 'DEFAULT';
}
来源:https://perlmaven.com/how-to-set-default-values-in-perl
在Perl中,我们可以使用很多种方式来设置默认值。下面是一些常用的方法:
这些方法都非常简单易懂,同时也能够有效地帮助我们在编写代码时避免出现未定义变量的错误。
substr)通过根据它们被使用的可能性对参数排序来处理此问题 - 不太频繁使用的参数出现在末尾并具有有用的默认值。
更简洁的方法是使用命名参数。Perl不直接支持命名参数,但可以使用哈希表模拟:
use 5.010; # for //
sub hello {
my %arg = @_;
my $say = delete $arg{say} // 'Hello';
my $to = delete $arg{to} // 'World!';
print "$say $to\n";
}
hello(say => 'Hi', to => 'everyone'); # Hi everyone
hello(say => 'Hi'); # Hi world!
hello(to => 'neighbor Bob'); # Hello neighbor Bob
hello(); # Hello world!
注意:定义或操作符//
是在Perl v5.10中添加的。它比使用逻辑或(||
)更健壮,因为它不会默认为逻辑上为假的值''
和0
。
false
传递给子例程怎么办?)。my $var = exists @_[0] ? shift : "Default_Value";
,但Perl的文档指出在数组上调用exists
已被弃用,所以我不推荐使用它。
Attribute::Default
文档页面的一部分: sub vitals : Default({age => 14, sex => 'male'}) {
my %vitals = @_;
print "I'm $vitals{'sex'}, $vitals{'age'} years old, and am from $vitals{'location'}\n";
}
# Prints "I'm male, 14 years old, and am from Schenectady"
vitals(location => 'Schenectady');
在其他答案中已经讨论了解决您问题的最佳方法。
但有一件事情引起了我的注意,那就是您说:
sub hello { print @_ || "Hello world"; }
And that works fine for if all you needed was one argument.
你实际上尝试过那段代码吗?它将打印参数的数量,或者在没有提供参数时,打印“Hello World”!
原因是 || 运算符具有优先级,并强制左侧处于标量上下文中,从而将 @_ 缩减为您提供的参数数量,而不是参数本身!
请查看 perlop 以获取有关 Perl 中运算符的更多信息。
希望对你有所帮助,
保罗
print $_[0] // "Hello world";
。正如ysth所说,你不能在数组上使用defined
(这就是//
的含义),因为在标量上下文中,一个数组返回其长度,它总是被定义的。 - cjm