你如何在Perl函数中获得多个参数?

pax*_*blo 14 perl shift

在我的代码中,我一直在使用函数调用中相当原始的提取参数方法,如下所示:

sub addSix ($$$$$$) {
    my ($a, $b, $c, $d, $e, $f) = (shift, shift, shift, shift, shift, shift);
    return $a + $b + $c + $d + $e + $f;
}

print addSix (1, 2, 3, 4, 5, 6) . "\n";
Run Code Online (Sandbox Code Playgroud)

(忘记原始代码,突出位是多次shift调用).

现在这对我来说似乎相当混乱,虽然Perl可能有类似的东西:

my ($a, $b, $c, $d, $e, $f) = shift (6);
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

但我找不到那样的东西.我知道我可以使用数组,但我想我仍然需要将数组解压缩到单个标量中.对于上面的示例情况来说这不会太糟糕,其中六个参数相似,但我对它们不适合作为数组的情况更感兴趣.

如何在不结束shift关键词的情况下提取参数?

Mat*_*Mat 32

你可以简单地输入:

my ($a, $b, $c, $d, $e, $f) = (@_);
Run Code Online (Sandbox Code Playgroud)

如果你没有那个原型,并且如果那个sub用超过六个参数调用,那么第六个之后的那个只是"不匹配",$f将被设置为第六个参数.

如果你想在第六个之后捕获所有参数,你可以这样做.

my ($a, $b, $c, $d, $e, $f, @others) = (@_);
Run Code Online (Sandbox Code Playgroud)

如果您的标量列表比右侧的列表长,则最后的元素将是undef.

  • `@ _`周围不需要`()` (9认同)
  • @Zaid:我发现在`=`的两边都有`()`的对称性更美观. (4认同)

Zai*_*aid 7

除非真正需要原型,否则不鼓励使用原型.

与Perl一样,有不止一种方法可以做到这一点.

这是保证仅添加传递的前六个参数的一种方法:

use List::Util 'sum';

sub addSix { sum @_[0..5] }
Run Code Online (Sandbox Code Playgroud)

或者,如果您喜欢自我记录代码:

sub addSix {

    my @firstSix = @_[0..5];  # Copy first six elements of @_
    return sum @firstSix;
}
Run Code Online (Sandbox Code Playgroud)

  • @paxdiablo:[`"原型不适用于参数验证"`](http://stackoverflow.com/a/3991173/133939) (2认同)

Jos*_*hua 5

我意识到这是一个旧线程,但它让我思考一种更好的方法来转换多个值。这只是一点乐趣......主要出于教育目的发布此内容。

当然,($x, $y) = @_如果您想保留 ,那很好@_,但也许您想出于某种原因改变您的论点?也许您需要由 中剩余参数的数量确定的任何附加子例程功能@_

我能想到的最干净的单行方法是使用一张简单的地图

sub shiftySub {
    map { $_ = shift } my ($v, $w, $x, $y);
    # @_ now has up to 4 items removed
    if (@_) { ... } # do stuff if arguments remain
}
Run Code Online (Sandbox Code Playgroud)
  • 如果提供 4 个参数,@_则子作用域中现在为空。
  • 如果提供 5 个参数,@_则子范围中剩余 1 个项目。
  • 如果提供 3 个参数,@_则为空,并且$y位于undef子范围内。

关于paxdiablo的理论shift(6)运算符,我们可以创建自己的函数来执行此操作......

sub shifter (\@;$) {
    my ( $array, $n ) = ( @_, 1 );
    splice( @$array, 0, $n );
}
Run Code Online (Sandbox Code Playgroud)

该函数通过强制传递引用原型(您应该使用原型的非常有限的原因之一)来确保数组在调用范围内移动。然后你就可以像这样简单地使用它......

my @items = ('one', 'two', 'three', 'four');
my ($x, $y) = shifter(@items, 2);
# or as a replacement for shift
my $z = shifter(@items)
# @items has 1 item remaining in this scope!
Run Code Online (Sandbox Code Playgroud)

当然,您也可以shifter在其他子程序中使用此功能。像这样的函数的主要缺点是您必须跟踪运算符两侧的赋值数量。

我希望my $post = 'informative' || 'interesting';