我仍然不清楚由参部分原因是显示为不定值%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)
在函数调用中使用参数(\%mkPara在您的情况下),您可以通过@_函数内的数组访问它们.
在这里,您将一个参数传递给函数:\%mkPara,然后您可以@_通过使用来访问第一个元素来访问它$_[0].
$_是一些内置函数/运算符的默认变量(print,m//和s///,chomp以及更多).通常见于while或for循环.但是在你的代码中,你没有理由使用它(你永远不会将它设置为任何东西,所以它仍然被设置为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你已经在看的.
起初这看起来有点棘手,但原因是它$_不一样@_.
来自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)