我仍然不清楚为什么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);
答案 0 :(得分:7)
在函数调用中使用参数(在您的情况下为\%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";
}
如果需要,您可以在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
}