如何在Perl中使用散列作为子例程的参数?

如何在Perl中使用散列作为子例程的参数?,perl,hash,parameters,subroutine,Perl,Hash,Parameters,Subroutine,我被要求修改一些现有代码以添加一些附加功能。我在谷歌上搜索过,似乎找不到答案。我有这样的想法 %first_hash = gen_first_hash(); %second_hash = gen_second_hash(); do_stuff_with_hashes(%first_hash, %second_hash); sub do_stuff_with_hashes { my %first_hash = shift; my %second_hash = shift;

我被要求修改一些现有代码以添加一些附加功能。我在谷歌上搜索过,似乎找不到答案。我有这样的想法

%first_hash = gen_first_hash();
%second_hash = gen_second_hash();
do_stuff_with_hashes(%first_hash, %second_hash);

sub do_stuff_with_hashes
{
    my %first_hash = shift;
    my %second_hash = shift;

    # do stuff with the hashes
}
我收到以下错误:

Odd number of elements in hash assignment at ./gen.pl line 85.
Odd number of elements in hash assignment at ./gen.pl line 86.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143.

第85行和第86行是子程序中的前两行,第124行和第143行是我访问散列的地方。当我查找这些错误时,它似乎表明我的哈希是未初始化的。但是,我可以验证哈希是否有值。为什么会出现这些错误?

当您将散列传递到函数中时,散列会被折叠成平面列表。因此,当您从函数的参数中移出一个值时,您只得到一个值。您要做的是通过引用传递散列

do_stuff_with_hashes(\%first_hash, \%second_hash);
但是,您必须使用散列作为引用

my $first_hash  = shift;
my $second_hash = shift;
首先

 do_stuff_with_hashes(%first_hash, %second_hash);
将散列“流”到列表中,相当于:

 ( 'key1_1', 'value1_1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )
然后选择其中一项,并且仅选择其中一项。所以

 my %first_hash = shift;
就像说:

 my %first_hash = 'key1_1'; 
 # leaving ( 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

您不能拥有像
{'key1'}
这样的散列,因为
'key1'
映射为空。

散列引用是一种方法,正如其他人所指出的那样

提供了另一种方法来实现这一点,因为谁需要临时变量

do_stuff_with_hashes( { gen_first_hash() }, { gen_second_hash() } );
在这里,您只需动态创建散列引用(通过函数调用周围的花括号),以便在do_stuff_with_散列函数中使用。这没什么特别的,其他方法同样有效,可能更清晰。如果您作为Perl新手在旅行中看到这种活动,这可能会有所帮助。

有点晚,但是

如前所述,必须传递引用,而不是散列

do_stuff_with_hashes(\%first_hash, \%second_hash);
但是,如果您需要/想要这样使用哈希,您可以立即取消对它们的引用

sub do_stuff_with_hashes {
    my %first_hash = %{shift()};
    my %second_hash = %{shift()};
};

没有
shift()
的解决方案速度更快,因为它不会复制内存中的数据,并且您可以在子例程中修改哈希。参见我的示例:

sub do_stuff_with_hashes($$$) {
    my ($str,$refHash1,$refHash2)=@_;
    foreach (keys %{$refHash1}) { print $_.' ' }
    $$refHash1{'new'}++;
}

my (%first_hash, %second_hash);
$first_hash{'first'}++;
do_stuff_with_hashes('any_parameter', \%first_hash, \%second_hash);
print "\n---\n", $first_hash{'new'};

这是一个复制品。请看一看谢谢你解释幕后发生的事情。很乐意效劳。如果您坚持使用Perl,需要记住的一件事是,每个人都会指出“有多种方法可以做到这一点”。在Perl编程中,这是一种祝福和诅咒(取决于您对这些事情的看法)。玩得高兴明确地说,我不是去引用散列,而是复制它们。