哈希复制并删除perl



我想备份哈希,保留原始哈希并使用备份的哈希数据。

并删除了备份哈希数据。

但是,原始哈希数据已删除。

这是代码。

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
================================

我认为这是一个哈希参考问题。

如何保留原始哈希并删除备份哈希?

您需要deep copyclone来复制完全哈希,而不仅仅是元素的第一级。

请参阅此处:

深层复制perl中的哈希的最佳方法是什么?

如果将引用分配给新变量,则不复制引用背后的值。相反,参考被复制。想象一下,您的名字是写在一张纸上的书。如果您给我一份论文的副本,我不会得到这本书的副本,只有引用该书的名称。

您需要复制每个参考。一种简单的方法是使用dclone从核心模块存储中。

use Storable 'dclone';
my %hash_backup = %{ dclone(%hash) };

如果您的数据结构平均小于三个级别,则您可能想查看克隆,该克隆声称其更快。

use Clone 'clone';
my %hash_backup = %{ clone(%hash) };

在这两种情况下,都可以参考。因为您想要哈希,而不是哈希参考,所以您需要传递新的ref %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。

您需要意识到的是多维数据结构在Perl中起作用的方式 - 它们通过参考来工作。

因此您没有哈希 - 您有哈希参考的哈希。

尝试:

print values %hash;

print $hash{data1};

您会看到类似的东西:

HASH(0x33cff8)

这是$hash{one}参考值的值。

您正在做的是在您的第二个哈希中添加参考。但是它指的是...仍然是原始的:

print $hash_backup{data1};

也将打印:

HASH(0x33cff8)

因此,它们不是两个单独的数据结构 - 它们都指的是同一子锤子。

关于解决方案是什么?好吧,这取决于您要完成的工作。复制这样的哈希人无法按照您的假设方式工作,因此您需要做其他事情。克隆它有多种方法,例如使用Storable,或者只是"手动"递归地行走钥匙。但是我建议首先考虑您的目标是什么,然后尝试找到适合的东西。

最新更新