我想备份哈希,保留原始哈希,并使用备份的哈希数据。
删除了备份哈希数据。
但是,原始哈希数据已被删除。
这是代码。
my %hash = (
'data1' => {
'data2' => {
'data3' => 'one',
},
},
);
foreach (1..3) {
my %hash_backup = %hash;
print $hash{'data1'}->{'data2'}->{'data3'},"\n";
print $hash_backup{'data1'}->{'data2'}->{'data3'},"\n";
print "-------------------------------\n";
delete $hash_backup{'data1'}->{'data2'};
print $hash{'data1'}->{'data2'}->{'data3'},"\n";
print $hash_backup{'data1'}->{'data2'}->{'data3'},"\n";
print "================================\n";
}
结果,
one
one
-------------------------------
================================
-------------------------------
================================
-------------------------------
================================
如果您更改删除代码,它将正常工作。
delete $hash_backup{'data1'};
结果,
one
one
-------------------------------
one
================================
one
one
-------------------------------
one
================================
one
one
-------------------------------
one
================================
我认为这是一个哈希引用问题。
如何保留原始哈希并删除备份哈希?
答案 0 :(得分:1)
如果为新变量分配引用,则不会复制引用后面的值。而是复制引用。想象一下,你有一本书写在一张纸上的名字。如果你给我一份那份文件的副本,我就不会得到这本书的副本,只有参考书的名字。
您需要复制每个参考文献。一种简单的方法是使用核心模块Storable中的dclone
。
use Storable 'dclone';
my %hash_backup = %{ dclone(\%hash) };
如果您的数据结构平均小于三个级别,您可能需要查看Clone,它声称速度更快。
use Clone 'clone';
my %hash_backup = %{ clone(\%hash) };
在这两种情况下,都需要参考。因为您需要哈希而不是哈希引用,所以您需要传递新的引用\%foo
并在出口%{ ... }
时取消引用。
如果您想自己完成此操作,则必须遍历数据结构,复制每个引用。要强制Perl复制数据而不是引用,您需要取消引用并创建新引用。
use strict;
use warnings;
use Data::Printer;
my $foo = { foo => 'bar' };
my $bar = { %$foo };
$bar->{foo} = 123;
p $foo;
p $bar;
此输出
\ {
foo "bar"
}
\ {
foo 123
}
我建议你阅读perlref和perlreftut。
答案 1 :(得分:1)
你需要意识到的是多维数据结构在perl中的工作方式 - 它们通过引用工作。
所以你没有哈希哈希 - 你有哈希引用的哈希。
尝试:
print values %hash;
或者
print $hash{data1};
你会看到类似的东西:
HASH(0x33cff8)
$hash{one}
的值引用的位置。
您正在做的是将引用添加到您的第二个哈希。但它所指的结构......仍然是最初的结构:
print $hash_backup{data1};
还会打印:
HASH(0x33cff8)
所以他们不是两个独立的数据结构 - 他们都指的是同一个子哈希。
关于解决方案是什么?嗯,这取决于你想要完成的事情。复制像这样的哈希并不像你假设的那样工作,所以你需要做一些其他事情。有各种克隆方法,例如使用Storable
,或者只是递归地手动操作按键'。但我建议首先考虑你的目标是什么,并尝试找到合适的东西。
答案 2 :(得分:1)
您需要deep copy
或clone
来复制完整哈希,而不仅仅是第一级元素。
见这里: