在我的代码中,我一直在使用函数调用中相当原始的提取参数方法,如下所示:
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
个关键字的情况下提取参数?
答案 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
}
@_
现在在子范围内为空。@_
在子范围内剩余1个项目。@_
为空,而$y
为undef
范围。关于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';