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

时间:2012-01-12 07:02:40

标签: 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";

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

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

my ($a, $b, $c, $d, $e, $f) = shift (6);

或类似的东西。

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

如何在不使用shift个关键字的情况下提取参数?

3 个答案:

答案 0 :(得分:32)

您只需输入:

即可
my ($a, $b, $c, $d, $e, $f) = (@_);

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

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

my ($a, $b, $c, $d, $e, $f, @others) = (@_);

如果您的标量列表长于右侧列表,则最后一个元素将为undef

答案 1 :(得分:7)

非常不鼓励使用原型,除非有真正的需要它。

与Perl一样,有多种方法可以做到。

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

use List::Util 'sum';

sub addSix { sum @_[0..5] }

或者如果你喜欢自我记录的代码:

sub addSix {

    my @firstSix = @_[0..5];  # Copy first six elements of @_
    return sum @firstSix;
}

答案 2 :(得分:3)

我意识到这是一个老线程,但它让我想到了一个更好的方法来转移多个值。这只是一点点乐趣......主要是出于教育目的而发布。

当然,如果你想保留($x, $y) = @_@_很棒,但也许你想因某种原因转移你的论点?也许您希望任何其他子例程功能由@_中的剩余参数数确定。

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

sub shiftySub {
    map { $_ = shift } my ($v, $w, $x, $y);
    # @_ now has up to 4 items removed
    if (@_) { ... } # do stuff if arguments remain
}
  • 如果提供了4个参数,则@_现在在子范围内为空。
  • 如果提供了5个参数,则@_在子范围内剩余1个项目。
  • 如果提供了3个参数,则@_为空,而$yundef 范围。

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

sub shifter (\@;$) {
    my ( $array, $n ) = ( @_, 1 );
    splice( @$array, 0, $n );
}

该函数通过强制执行pass-by-ref原型(您应该使用原型的一个非常有限的原因)来确保数组在调用范围内移位。然后你就像这样使用它......

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!

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

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