简体   繁体   English

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

[英]How to pass a hash by reference in perl

I know this should be easily searchable on google, not to mention a trivial use of perl, but I've tried many solutions I've found and so far none of them gives the expected behavior. 我知道这应该可以在谷歌上轻松搜索,更不用说perl的一个微不足道的使用,但我已经尝试了很多解决方案,我发现它们到目前为止都没有给出预期的行为。 Essentially, I'm trying to call a subroutine, return a reference to a hash from that subroutine, pass a reference to that hash to another subroutine, and then print the contents of that hash, via code similar to the following: 本质上,我正在尝试调用子例程,从该子例程返回对哈希的引用,将对该哈希的引用传递给另一个子例程,然后通过类似于以下的代码打印该哈希的内容:

#!/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;
}

Can someone tell me the best way of doing this (via subroutines) without creating an extra copy of the hash? 可以有人告诉我这样做的最佳方式(通过子程序)而不创建哈希的额外副本吗? The solutions I've tried have not printed out any lines starting with "3". 我试过的解决方案没有打印出以“3”开头的任何行。

You have to pull the parameters in as a reference and then dereference it: 您必须将参数作为参考拉出,然后取消引用它:

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

Anytime you make a reference, you have to explicitly dereference it. 无论何时进行引用,都必须明确取消引用它。 Also, beware that any changes to the reference will change the original. 另外,请注意对引用的任何更改都将更改原始内容。 If you want to avoid changing the original, you can either pass the hash as a list: 如果您想避免更改原始内容,可以将哈希值作为列表传递:

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";
    }
}

Or copy the hash reference into a new hash: 或者将哈希引用复制到新哈希中:

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";
    }
}

Everything else is good, so I'm just going to concentrate on print_foo... 其他一切都很好,所以我只专注于print_foo ......

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

FYI, you need to realize that %loc is now a COPY of the hash (I asked a question which explains this here: Confusion about proper usage of dereference in Perl ). 仅供参考,你需要意识到%loc现在是哈希的副本(我在这里问了一个问题解释了这个问题: 关于在Perl中正确使用dereference的困惑 )。 To avoid making a copy... 为了避免复制......

sub print_foo
{
    my $loc = shift @_;
    foreach $key (sort keys %$loc) {
        my $val = $loc->{$key}
        print "3 $key $val\n";
    }
}

You want to convert that from a reference to a hash like so: 您希望将其从引用转换为哈希,如下所示:

my %loc = %{@_[0]};

or 要么

my %loc = %{shift};

You can also keep it as a reference: 您也可以将其作为参考:

my $locref = shift;
foreach $key (sort keys %$locref}) {
    print "3 $key $locref->{$key}\n";
}

This information can be found by typing perldoc perlref at the command line. 可以通过在命令行键入perldoc perlref到此信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM