我有一个问题。 如果我将一个哈希(哈希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
!我希望哈希值保留原始值。
我该怎么做?
答案 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}
中哈希的引用。
有关更多信息,请参见...