如何在perl中通过引用传递哈希

jon*_*rry 10 perl

我知道这应该可以在谷歌上轻松搜索,更不用说perl的微不足道的使用了,但我已经尝试了很多我找到的解决方案,到目前为止它们都没有给出预期的行为.本质上,我正在尝试调用子例程,从该子例程返回对哈希的引用,将对该哈希的引用传递给另一个子例程,然后通过类似于以下的代码打印该哈希的内容:

#!/usr/bin/perl                                                                                                                                                                                                   

my $foo = make_foo();

foreach $key (sort keys %$foo) {
    print "2 $key $$foo{$key}\n";
}

print_foo(\%foo);

sub print_foo
{
    my %loc = ???;
    foreach $key (sort keys %loc}) {
        print "3 $key $loc{$key}\n";
    }
}

sub make_foo
{
    my %ret;
    $ret{"a"} = "apple";
    foreach $key (sort keys %ret) {
        print "1 $key $ret{$key}\n";
    }
    return \%ret;
}
Run Code Online (Sandbox Code Playgroud)

可以有人告诉我这样做的最佳方式(通过子程序)而不创建哈希的额外副本吗?我试过的解决方案没有打印出以"3"开头的任何行.

zos*_*tay 10

您必须将参数作为参考拉出,然后取消引用它:

sub print_foo
{
    my ($loc) = @_;
    foreach my $key (sort keys %$loc) {
       print "3 $key $loc->{$key}\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

无论何时进行引用,都必须明确取消引用它.另外,请注意对引用的任何更改都将更改原始内容.如果要避免更改原始内容,可以将哈希值作为列表传递:

print_foo(%foo); # flattens the hash to a list and passes it in through @_

sub print_foo
{
    my (%loc) = @_; # load the hash from the list
    foreach my $key (sort keys %loc) {
       print "3 $key $loc{$key}\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

或者将哈希引用复制到新哈希中:

sub print_foo
{
    my ($ref_loc) = @_; # changes to %$ref_loc will change %foo
    my %loc = %$ref_loc; # COPY, changes to %loc do not change %foo
    foreach my $key (sort keys %loc}) {
       print "3 $key $loc{$key}\n";
    }
}
Run Code Online (Sandbox Code Playgroud)