首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将可选参数传递给Perl函数?

如何将可选参数传递给Perl函数?
EN

Stack Overflow用户
提问于 2011-11-14 23:48:51
回答 3查看 41.3K关注 0票数 19

我想向一个函数传递几个参数,其中一个是可选的。据我所知,唯一的方法是使用列表(@)作为参数。因此,它不包含任何内容或包含1个元素(永远不会是undef),因此我可以使用以下代码:

代码语言:javascript
复制
sub someFunction($$@) {
    my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
    ...
} 

这段代码可以工作,但我觉得这可能不是最好的解决方法。

有没有其他的方法呢?

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-11-14 23:52:13

您可以在原型中使用分号来表示所需参数的结尾:

代码语言:javascript
复制
sub someFunction($$;$) {
  my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
  ...
}

@%之前,;是可选的,根据the docs的说法,这两种语言“吞噬了所有其他东西”。

编辑:正如DVK在评论中指出的( TLP在这里的另一个答案中强调),你最好避免使用原型:

代码语言:javascript
复制
sub someFunction {
  my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
  ...
}

Perl原型有其用途(主要用于为参数提供隐式上下文强制,就像Perl的内置函数一样)。它们应该使用作为一种机制来检查函数是否使用正确数量和类型的参数调用。

票数 19
EN

Stack Overflow用户

发布于 2011-11-15 00:15:49

Prototypes (子声明的($$@)部分)本身是可选的。它们有一个非常特殊的用途,如果你不知道它是什么,最好不要使用它。来自perlsub:

...the此功能的主要目的是让您定义像内置函数一样工作的子例程

只需从sub声明中删除原型,您就可以使用任何您喜欢的参数。

代码语言:javascript
复制
sub someFunction {
    my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
    if (defined $option_param) {
        # do optional things
    }
    $option_param //= "default optional value";
    ....
} 
票数 40
EN

Stack Overflow用户

发布于 2011-11-15 00:30:11

$parameter hashref中对参数进行分组是一个好主意。如果需要提供几个选项(强制或可选),这一点尤其有用。

要访问任何参数,只需使用$parameter->{oblig1}$$parameter{option2}

传递hashrefs使其在开发时特别方便,因此当需要$oblig3时,参数的顺序既不会在调用方更改,也不会在sub本身更改。前后比较:

代码语言:javascript
复制
# 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,不需要担心参数顺序:

代码语言:javascript
复制
--------------------------+-------------------------
# Caller                  | # Sub
--------------------------+-------------------------
someFunc({ oblig1  => 1   | sub {
           oblig2  => 2   |   my ( $params ) = @_;
           option1 => 1   |   # No changes to    
           oblig3  => 7   |   # argument passing
         });              |  }    
                          | 
--------------------------+-------------------------

根据子例程的设计需要,可以使用以下子例程参数模式:

  1. 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 };

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8124138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档