Perl 将嵌套哈希传递给子例程

Perl 将嵌套哈希传递给子例程,perl,hash,Perl,Hash,我有一个多维散列,如下所示: my %hashTable; $hashTable{'1'}{'A'} = "red"; $hashTable{'1'}{'B'} = "blue"; $hashTable{'2'}{'A'} = "orange"; $hashTable{'2'}{'B'} = "purple"; 我想将一个内部散列作为参数传递给一个子例程。 比如说, hashFunc($hashTable{'2'}); sub hashFunc{ my %innerHash = $

我有一个多维散列,如下所示:

my %hashTable;
$hashTable{'1'}{'A'} = "red";
$hashTable{'1'}{'B'} = "blue";
$hashTable{'2'}{'A'} = "orange";
$hashTable{'2'}{'B'} = "purple";
我想将一个内部散列作为参数传递给一个子例程。 比如说,

hashFunc($hashTable{'2'});

sub hashFunc{
     my %innerHash = $_[0];
}
但是,当我将函数调用为
hashFunc($hashTable{'2'})
时,我收到了错误

Reference found where even-sized list expected

如何正确地提供内部哈希作为子例程的参数?

如果需要将内部哈希用作哈希,则需要取消对其的引用

您可以在子例程中执行此操作

hashFunc($hashTable{2});
sub hashFunc {
    my %innerHash = %{ $_[0] };
或者在调用代码中

hashFunc(%{ $hashTable{2} });
sub hashFunc {
    my %innerHash = @_;
但是,您通常不需要使用散列,您可以直接使用散列引用

hashFunc($hashTable{2});
sub hashFunc {
    my $innerHashRef = shift;
    # Whatever you need to do with the hash:
    $innerHashRef->{key}{A} = ... 
    for my $key (keys %$innerHashRef) {
    ...

多维数据结构通过引用进行组装

$hashtable{'2'}
是一个标量值,它是对散列的引用

要在子例程中使用它,您需要在发送它之前取消引用它:

hashFunc( %{$hashtable{'2'}});
它将发送一个值列表(然后您可以像这样将其分配到哈希中)

或者在散列中:

 my %innerHash = %{$_[0]};
然而,正如Borodin指出的,这将导致数据结构被复制,这是低效的,而且很少有必要

所以你可以:

 my ( $innerHash ) = @_; 
然后,您可以通过解引用运算符访问
$innerHash
,如:

 print $innerHash -> {'A'};
 foreach my $key ( keys %$innerHash ) { 
    print $key,"\n";
 }

等等。

Perl哈希值必须是标量,嵌套数据结构是通过对每个数组或哈希值的哈希或数组的引用来构建的

您需要在子例程中指定一个标量值,如下所示

hashFunc($hashTable{'2'});

sub hashFunc{
    my ($innerHash) = @_;
    # same as my $innerHash = $_[0]
    ...
}
您没有说明要对次散列执行什么操作,但通常可以使用
$innerHash->{key}
访问内部散列的元素,或者可以通过取消引用值来使用
每个
运算符;例如,
对于我的$k(键%$innerHash){…}


您应该查看并了解更多信息

您使用的是什么版本的perl。我没有得到这个代码的任何错误。我也没有得到这个错误。请详细说明您的环境。这绝对是每个perl版本中的一个错误。如果看不到,请打开警告。是否确实不需要执行
my%innerHash=@在第二种情况下?这与问题相同。取消对整个散列的引用是浪费,而且几乎肯定是不必要的,绝对不是!提出这两种解决方案中的任何一种都会产生误导。取消对散列的引用很少是必要的,而且结果是原始数据的一级副本,这将不必要地复制数据,这一点也不明显。引用应直接传递给子例程