我更喜欢使用
sub do_something_fantastical {
my ( $foo, $bar, $baz, $qux, $quux, $corge ) = @_;
}
因为它更具可读性。当这段代码不经常被调用时,它是值得的。在极少数情况下,您希望经常调用 make 函数而不是直接使用 @_ 。它仅对非常短的函数有效,并且您必须确保该函数将来不会发展(一次编写函数)。在这种情况下,我在 5.8.8 中进行了基准测试,单个参数的 shift 比 $_[0] 快,但对于两个参数,使用 $_[0] 和 $_[1] 比 shift、shift 快。
sub fast1 { shift->call(@_) }
sub fast2 { $_[0]->call("a", $_[1]) }
但回到你的问题。我也更喜欢以这种方式在一行中对许多参数进行@_赋值
sub do_something_fantastical2 {
my ( $foo, $bar, $baz, @rest ) = @_;
...
}
当 Suspect @rest 不会太大时。在其他情况下
sub raise {
my $inc = shift;
map {$_ + $inc} @_;
}
sub moreSpecial {
my ($inc, $power) = (shift(), shift());
map {($_ + $inc) ** $power} @_;
}
sub quadratic {
my ($a, $b, $c) = splice @_, 0, 3;
map {$a*$_*$_ + $b*$_ + $c} @_;
}
在极少数情况下,我需要尾调用优化(当然是手动),然后我必须直接使用 @_,而不是短函数值得。
sub _switch #(type, treeNode, transform[, params, ...])
{
my $type = shift;
my ( $treeNode, $transform ) = @_;
unless ( defined $type ) {
require Data::Dumper;
die "Broken node: " . Data::Dumper->Dump( $treeNode, ['treeNode'] );
}
goto &{ $transform->{$type} } if exists $transform->{$type};
goto &{ $transform->{unknown} } if exists $transform->{unknown};
die "Unknown type $type";
}
sub switchExTree #(treeNode, transform[, params, ...])
{
my $treeNode = $_[0];
unshift @_, $treeNode->{type}; # set type
goto &_switch; # tail call
}
sub switchCompact #(treeNode, transform[, params, ...])
{
my $treeNode = $_[0];
unshift @_, (%$treeNode)[0]; # set type given as first key
goto &_switch; # tail call
}
sub ExTreeToCompact {
my $tree = shift;
return switchExTree( $tree, \%transformExTree2Compact );
}
sub CompactToExTree {
my $tree = shift;
return switchCompact( $tree, \%transformCompact2ExTree );
}
其中 %transformExTree2Compact 和 %transformCompact2ExTree 是具有 key 类型和 value 中的 code ref 的哈希值,可以尾调用 switchExTree 或 switchCompact 它自己。但是这种方法很少真正需要,并且必须让不太值得的大学动用手指。
总之,可读性和可维护性是必须的,尤其是在 perl 中,@_ 在一行中的分配更好。如果你想设置默认值,你可以在它之后进行。