如何在perl中通过引用传递散列

发布于 2024-12-21 00:06:17 字数 841 浏览 0 评论 0原文

我知道这应该很容易在谷歌上搜索到,更不用说对 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;
}

有人能告诉我吗?我在不创建哈希的额外副本的情况下执行此操作的最佳方法(通过子例程)?我尝试过的解决方案没有打印出任何以“3”开头的行。

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. 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".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩心不撩汉 2024-12-28 00:06:17

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

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

无论何时进行引用,都必须显式取消引用它。另外,请注意,对引用的任何更改都会更改原始引用。如果您想避免更改原始哈希,可以将哈希作为列表传递:

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

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

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

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";
    }
}
能怎样 2024-12-28 00:06:17

其他一切都很好,所以我只专注于 print_foo...

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

仅供参考,您需要意识到 %loc 现在是哈希的副本(我问了一个问题,在这里解释了这一点: 关于 Perl 中取消引用的正确使用的混乱)。为了避免复印...

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

Everything else is good, so I'm just going to concentrate on 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 ). 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";
    }
}
云雾 2024-12-28 00:06:17

您希望将其从引用转换为散列,如下所示:

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

或者

my %loc = %{shift};

您也可以将其保留为引用:

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

可以通过在命令行中键入 perldoc perlref 找到此信息。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文