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

use*_*084 2 perl hash

我仍然不清楚由参部分原因是显示为不定值%Q$_初始化.我一直在寻找perlreftut,仍然无法看到我做错了什么.将散列作为平面数组传递没有问题.

通过ref执行它testRef(\%mkPara)会传递对子例程的标量哈希引用,对吧?那么,是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); 
Run Code Online (Sandbox Code Playgroud)

Dad*_*ada 7

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

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

$_是一些内置函数/运算符的默认变量(print,m//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";
}
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以在perlsub上找到有关函数的更多信息.

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

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

有很多关于在线参考的资源,例如perlreftut你已经在看的.


Zai*_*aid 6

起初这看起来有点棘手,但原因是它$_不一样@_.

来自perlvar:

  • $_是隐式/"默认"变量,不必为某些函数明确拼写(例如split)
  • 在子例程中,数组@_包含传递给该子例程的参数

所以之所以如此

my %Q = %{$_};
Run Code Online (Sandbox Code Playgroud)

表示你不能使用未定义的值作为哈希引用是因为$_没有定义.

你真正需要的是

my %Q = %{$_[0]};
Run Code Online (Sandbox Code Playgroud)

因为那是第一个元素@_,也就是首先传递给它的元素testRef.


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

sub testRef {

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