我应该使用$ _ [0]还是复制Perl中的参数列表?

use*_*033 3 perl hash

如果我将哈希传递给子:

parse(\%data);
Run Code Online (Sandbox Code Playgroud)

我应该$_[0]首先使用变量还是可以$_[0]在我想从哈希中获取元素时继续访问?澄清:

sub parse
{    $var1 = $_[0]->{'elem1'};
     $var2 = $_[0]->{'elem2'};
     $var3 = $_[0]->{'elem3'};
     $var4 = $_[0]->{'elem4'};
     $var5 = $_[0]->{'elem5'};
}
# Versus
sub parse
{    my $hr = $_[0];
     $var1 = $hr->{'elem1'};
     $var2 = $hr->{'elem2'};
     $var3 = $hr->{'elem3'};
     $var4 = $hr->{'elem4'};
     $var5 = $hr->{'elem5'};
}
Run Code Online (Sandbox Code Playgroud)

第二个版本是否更正确,因为它不必继续访问参数数组,或者Perl最终是否以相同的方式互相干扰它们?

Iva*_*uev 11

在这种情况下没有区别,因为您正在传递对哈希的引用.但是在传递标量的情况下会有区别:

sub rtrim {
    ## remove tailing spaces from first argument
    $_[0] =~ s/\s+$//;
}
rtrim($str); ## value of the variable will be changed

sub rtrim_bugged {
    my $str = $_[0]; ## this makes a copy of variable
    $str =~ s/\s+$//;
}
rtrim($str); ## value of the variable will stay the same
Run Code Online (Sandbox Code Playgroud)

如果您要传递哈希引用,则只创建引用副本.但哈希本身也是一样的.因此,如果您关心代码可读性,那么我建议您为所有参数创建一个变量.例如:

sub parse {
     ## you can easily add new parameters to this function
     my ($hr) = @_; 

     my $var1 = $hr->{'elem1'};
     my $var2 = $hr->{'elem2'};
     my $var3 = $hr->{'elem3'};
     my $var4 = $hr->{'elem4'};
     my $var5 = $hr->{'elem5'};
}
Run Code Online (Sandbox Code Playgroud)

此外,更具描述性的变量名称也将改进您的代码.


Eth*_*her 7

有关直接shift访问vs 的效率的一般性讨论@_,请参阅:

至于你的具体代码,我会使用shift,但使用哈希切片简化数据提取:

sub parse
{
    my $hr = shift;
    my ($var1, $var2, $var3, $var4, $var5) = @{$hr}{qw(elem1 elem2 elem3 elem4 elem5)};
}
Run Code Online (Sandbox Code Playgroud)

我会认为,这种方法确实别的东西用这些变量,使得它值得让他们在不同的变量(也许是哈希是只读的,你需要将它们插入到其他一些数据之前进行一些修改?) - 否则为什么不把它们留在他们开始的hashref中呢?

  • 哈希切片+1,世界被遗忘的奇迹. (5认同)
  • 除了一个例外,我更愿意避免转移`@ _`并从中做一个列表赋值 - 即使是一个参数,因为这意味着我不会因为意外地将'my $ one = shift`转换为bug而引入错误`my($ one,$ two)= shift`.例外是在OO代码中(特别是构造函数,或委托或重新调度的函数),其中转换`$ self`使事情变得更简单. (2认同)

yst*_*sth 5

你是微观优化; 尽量避免这种情况.选择最易读/可维护的内容.通常这将是你使用词法变量的那个,因为它的名字表示它的目的......但是如果你使用类似的名称$data或者$x这显然不适用.

就技术细节而言,在大多数情况下,您可以通过计算perl将使用的基本操作数来估计所花费的时间.对于你来说$_[0],非词法数组变量中的元素查找需要多个操作:一个用于获取glob,一个用于获取glob的数组部分,一个用于获取索引(只有一个用于常量),以及一个查找元素. $hr另一方面,是一个单一的操作.为了迎合@_的直接用户,有一个优化可以减少$_[0]单个组合op的操作(当索引介于0和255之间时),但是在你的情况下没有使用它,因为hash-deref上下文要求数组元素查找上的附加标志(以支持自动生成),优化的操作系统不支持该标志.

总而言之,使用词汇将更具可读性(如果您不止一次使用它),并且在不知不觉中更快.