我想向一个函数传递几个参数,其中一个是可选的。据我所知,唯一的方法是使用列表(@)作为参数。因此,它不包含任何内容或包含1个元素(永远不会是undef),因此我可以使用以下代码:
sub someFunction($$@) {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
这段代码可以工作,但我觉得这可能不是最好的解决方法。
有没有其他的方法呢?
谢谢。
发布于 2011-11-14 23:52:13
您可以在原型中使用分号来表示所需参数的结尾:
sub someFunction($$;$) {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
在@
或%
之前,;
是可选的,根据the docs的说法,这两种语言“吞噬了所有其他东西”。
编辑:正如DVK在评论中指出的( TLP在这里的另一个答案中强调),你最好避免使用原型:
sub someFunction {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
Perl原型有其用途(主要用于为参数提供隐式上下文强制,就像Perl的内置函数一样)。它们应该使用作为一种机制来检查函数是否使用正确数量和类型的参数调用。
发布于 2011-11-15 00:15:49
Prototypes (子声明的($$@)
部分)本身是可选的。它们有一个非常特殊的用途,如果你不知道它是什么,最好不要使用它。来自perlsub:
...the此功能的主要目的是让您定义像内置函数一样工作的子例程
只需从sub声明中删除原型,您就可以使用任何您喜欢的参数。
sub someFunction {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
if (defined $option_param) {
# do optional things
}
$option_param //= "default optional value";
....
}
发布于 2011-11-15 00:30:11
在$parameter
hashref中对参数进行分组是一个好主意。如果需要提供几个选项(强制或可选),这一点尤其有用。
要访问任何参数,只需使用$parameter->{oblig1}
或$$parameter{option2}
。
传递hashrefs使其在开发时特别方便,因此当需要$oblig3
时,参数的顺序既不会在调用方更改,也不会在sub本身更改。前后比较:
# BEFORE $oblig3
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc( $oblig1, | sub {
$oblig2, | my ( $oblig1,
$option1 ); | $oblig2,
| $option1 ) = @_;
| }
--------------------------+-------------------------
# AFTER $oblig3
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc( $oblig1, | sub {
$oblig2, | my ( $oblig1,
$oblig3, | $oblig2,
$option1 ); | $oblig3,
| $option1 ) = @_;
| }
--------------------------+-------------------------
调用方和sub的参数顺序都会发生变化,因此需要维护和遵守顺序。
使用hashrefs,不需要担心参数顺序:
--------------------------+-------------------------
# Caller | # Sub
--------------------------+-------------------------
someFunc({ oblig1 => 1 | sub {
oblig2 => 2 | my ( $params ) = @_;
option1 => 1 | # No changes to
oblig3 => 7 | # argument passing
}); | }
|
--------------------------+-------------------------
根据子例程的设计需要,可以使用以下子例程参数模式:
my ( $mandatory_parameters, $optional_parameters ) = @_;
如果每个模式都有几个,则此模式很有用。这种方法的美妙之处在于,如果不传递,$optional_parameters
是未定义的,因此默认情况下可以执行if ! $optional_parameters;
请注意,随后需要检查必选参数:
对于( qw/ a b c/){ }
my ( $parameters ) = @_;
“缺少'$_‘参数\n”,除非存在$mandatory_parameters->{$_};如果只有很少的强制参数或没有强制参数,则非常有用。
如果传递参数只是为了修改默认行为,这也是非常有效的。通过在包的作用域中定义$default_parameters
,除非显式传递了参数,否则可以通过后续的一行程序加载缺省值:
$parameters = { %$default_parameters, %$parameters };
https://stackoverflow.com/questions/8124138
复制相似问题