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;を作成すると、トップレベルのキーしか取得されないため、誤った結果が得られます。キーを持つ 2 番目のレベル'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

これは、ハッシュの「第 2 レベル」 (IOW: キー「abc」の値) 自体がハッシュ参照であるためです。$value_ref割り当てで参照されているハッシュの内容をコピーしている間:

my %value = %$value_ref;

...これは「浅い」コピーのみを行っています。

キー「xyz」の値を変更すると、サブに渡された元の構造にある同じハッシュが変更されます。

于 2013-11-08T19:01:34.083 に答える