Perl中的HASH值是否实质上是内存位置?

时间:2018-07-10 22:49:25

标签: perl hash reference

我有一个问题。 如果我将一个哈希(哈希A)的值分配给另一个哈希(哈希B),然后更改哈希B的值,哈希A也将更改。我该如何避免?

例如

$hashB{a}{b}{c} = 5;

$hashA{a}{b} = $hashB{a}{b};

$hashA{a}{b}{c} = 7;

现在$hashB{a}{b}{c} = 7!我希望哈希值保留原始值。

我该怎么做?

1 个答案:

答案 0 :(得分:5)

  

Perl中的HASH值是否实质上是内存位置?

是的,但是可以防止直接访问内存。我们称它们为“参考”。 “哈希哈希”实际上是对其他哈希的引用哈希。 Perl将自动为您创建中间哈希,此过程称为“自动生存”。

my %hashB;
$hashB{a}{c}{d} = 5;
print $hashB{a}{c}{d};

让我们扩展此示例,以使所有自动生存明确。我将使用简单的字母而不是变量,因此我们不必定义它们。

my %hashB;

# $hashB{a}{c}{d} = 5;
my $hashD = { d => 5 };
my $hashC = { c => $hashD };
$hashB{a} = $hashC;

# print $hashB{a}{c}{d};
$hashC = $hashB{a};
$hashD = $hashC->{c};
print $hashD->{d};

这是Perl在幕后所做的全部工作。每个嵌套级别都是其自己的哈希。

请注意,哈希值仅是标量,单个值。如果您尝试这样做...

$hashB{q} = %hashQ;

...您会得到一些非常奇怪的东西。在这种情况下,Perl尝试将%hashQ视为标量。散列作为标量是散列中的存储桶数,类似于1/8。不太有用。

您能做的就是这个。

$hashB{q} = \%hashQ;

与其他语言中的指针一样,它引用了%hashQ,并将其分配给$hashB{q}

现在,如果您对$hashB{q}中的键进行更改,实际上您将在更改%hashQ

use strict;
use warnings;
use v5.10;

my %hashQ = ( foo => 23 );
my %hashB;

# assign a reference to %hashQ
$hashB{q} = \%hashQ;
say $hashB{q}{foo};     # 23
say $hashQ{foo};     # 23

# change %hashQ via a reference
$hashB{q}{foo} = 42;
say $hashB{q}{foo};  # 42
say $hashQ{foo};     # 42

# change %hashQ directly
$hashQ{foo} = 99;
say $hashB{q}{foo};  # 99
say $hashQ{foo};     # 99

另一方面,复制Perl中的简单字符串和数字值。所以在您的示例中...

$hashB{$a}{$c}{$d} = 5; # assign 5

$hashA{$a}{$b}{$c}{$d} = $hashB{$a}{$c}{$d}; # COPY 5

$hashA{$a}{$b}{$c}{$d} = 7; # assign 7

$hashB{$a}{$c}{$d}仍为5,因为其值5已被复制。

另一方面,如果您这样做...

$hashB{$a}{$c}{$d} = 5; # assign 5

$hashA{$a}{$b}{$c} = $hashB{$a}{$c}; # copy a reference

$hashA{$a}{$b}{$c}{$d} = 7; # assign 7

现在$hashB{$a}{$c}{$d}是7,因为您复制了对$hashB{$a}{$c}中哈希的引用。


有关更多信息,请参见...