5

我正在使用 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 的方式有关。我错过了什么?

4

2 回答 2

7

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

幸运的是,有一个 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
于 2013-11-08T19:04:18.687 回答
3

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

my %value = %$value_ref;

...这只是做一个“浅”的副本。

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

于 2013-11-08T19:01:34.083 回答