Perl:使用rule1通过ref传递哈希

时间:2016-10-15 09:53:44

标签: perl hash

我仍然不清楚为什么ref部分显示%Q$_未初始化的未定义值。我一直在查看perlreftut但仍然无法看到我做错了什么。将散列作为平面数组传递没有问题。

使用testRef(\%mkPara)参考ref,将标量哈希引用传递给子例程,对吧?那么,my %Q = %{$_}不会把它变成哈希吗?

use strict;
use diagnostics;
use warnings;

my %mkPara = ('aa'=>2,'bb'=>3,'cc'=>4,'dd'=>5);

sub testFlat
{
    my %P = @_;
    print "$P{'aa'}, $P{'bb'}, ", $P{'cc'}*$P{'dd'}, "\n";  
}

sub testRef
{
    my %Q = %{$_}; #can't use an undefined value as HASH reference
    #print  $_->{'aa'}, "\n";#Use of uninitialized value
    print $Q{'aa'},"\n";
}

#testFlat(%mkPara);
testRef(\%mkPara); 

2 个答案:

答案 0 :(得分:7)

在函数调用中使用参数(在您的情况下为\%mkPara)时,可以通过函数内的@_数组访问它们。

在这里,您将一个参数传递给函数\%mkPara,然后您可以通过使用@_访问$_[0]的第一个元素来访问该函数。

$_是一些内置函数/运算符(printm//s///chomp等等的默认变量。通常在whilefor循环中看到。但是在您的代码中,您没有理由使用它(您永远不会将其设置为任何内容,因此它仍然设置为undef,因此错误"Can't use an undefined value as a HASH reference"

所以你的功能应该是:

sub testRef
{
    my %Q = %{$_[0]}; # instead of %{$_}
    print  $_[0]->{'aa'}, "\n"; # instead of $_->{'aa'}
    print $Q{'aa'},"\n";
}

如果需要,您可以在perlsub上找到有关功能的更多信息。

然而,正如@Ikegami在评论中指出的那样,使用my %Q = %{$_[0]};创建了您发送给该函数的哈希的副本,在大多数情况下(包括您刚才的那个)打印哈希的一个键是非常不理想的,因为你可以使用hashref(就像你在做$_[0]->{'aa'}时那样)。
您可以使用这样的哈希引用(与@Zaid的答案大致相同):

sub testRef
{
    my ( $Q ) = @_;
    print $Q->{aa} ;
    print $_, "\n" for keys %$Q;
}
testRef(\%mkPara); 

有大量关于在线参考资源的资源,例如您已经在查看的perlreftut

答案 1 :(得分:6)

起初看起来有点棘手,但原因是$_@_不同。

来自perlvar

  • $_是隐式/“默认”变量,无需为某些功能明​​确拼写(例如split
  • 在子例程中,数组@_包含传递给该子例程的参数

所以

的原因
my %Q = %{$_};

表示您不能使用未定义的值作为哈希引用,因为$_未定义。

你真正需要的是

my %Q = %{$_[0]};

因为这是@_的第一个元素,这是首先传递给testRef的元素。

在实践中,我倾向于发现自己的做法有所不同,因为它有助于未来修改的灵活性:

sub testRef {

    my ( $Q ) = @_;
    print $_, "\n" for keys %$Q;  # just as an example
}