【问题标题】:Perl: Hash values change after returning from a subroutinePerl:从子例程返回后哈希值发生变化
【发布时间】:2013-11-20 21:23:04
【问题描述】:

我正在使用 perl 中的哈希,但不明白为什么哈希值会在以下内容中发生变化:

use strict;

sub test
{
    my ($value_ref) = @_;
    my %value = %$value_ref;
    $value{'abc'}{'xyz'} = 1;
}

my %hash;
$hash{'abc'}{'xyz'} = 0;
test (\%hash);
print "$hash{'abc'}{'xyz'}\n";

上面返回1,为什么不像这里返回0呢?

use strict;

sub test
{
    my ($value_ref) = @_;
    my %value = %$value_ref;
    $value{'abc'} = 1;
}

my %hash;
$hash{'abc'} = 0;
test (\%hash);
print "$hash{'abc'}\n";

我想这与我传递 %hash 的方式有关。我错过了什么?

【问题讨论】:

    标签: perl hash return-value subroutine


    【解决方案1】:

    您得到的结果不正确,因为当您使用my %value = %$value_ref; 制作散列的副本 时,您只能获得顶级密钥。第二个级别,键为'xyz',是实际存储值的级别,因此对该reference 的任何更改都会被保留。当您需要 副本时,您正在执行 副本。

    幸运的是,有一个 CPAN 模块!

    use strict;
    use Storable qw(dclone);
    
    sub test
    {
        my ($value_ref) = @_;
        my %value = %{ dclone($value_ref) };
        $value{'abc'}{'xyz'} = 1;
    }
    
    my %hash;
    $hash{'abc'}{'xyz'} = 0;
    test (\%hash);
    print "$hash{'abc'}{'xyz'}\n"; # prints 0
    

    【讨论】:

    【解决方案2】:

    这是因为散列的“第二级”(IOW:键 'abc' 的值)本身就是一个散列引用。当您在作业中复制 $value_ref 引用的哈希内容时:

    my %value = %$value_ref;
    

    ...这只是做一个“浅”的复制。

    当您修改键“xyz”的值时,您正在修改传递给子的原始结构中的相同哈希。

    【讨论】:

      猜你喜欢
      • 2014-07-02
      • 2013-04-30
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-06
      • 2017-04-07
      相关资源
      最近更新 更多