在Perl中复制hashref

时间:2011-08-16 18:52:39

标签: perl

  

可能重复:
  What's the best way to make a deep copy of a data structure in Perl?

我显然误解了一些关于hashrefs在Perl中是如何工作的,并且我正在寻找纠正它。

我需要获得一个hashref的副本,我可以在不修改原始文件的情况下进行操作。根据{{​​3}},复制hashref就像使用equals运算符一样简单:

my $hashref_copy = $hashref;

但据我所知,所有这一切都是使$hashref_copy指向原始对象的指针。考虑这个玩具代码:


my $hashref = {data => "fish"};

my $hashref_copy = $hashref;
$hashref_copy->{data} = "chips";

print "$hashref->{data}\n";

如果$hashref_copy真的是一个独立的副本,我希望这段代码能打印出“鱼”。相反,它打印“筹码”。

所以要么1)我误解了一些事情或2)Perl被打破了。我很确定它不是#2,尽管我的自我会让我思考。

我哪里错了?我需要做些什么来修改$hashref_copy 而不是才能显示在原始$hashref中?

3 个答案:

答案 0 :(得分:62)

将hashref复制到另一个标量时,您将复制对同一哈希的引用。这类似于将一个指针复制到另一个指针,但不会更改任何指向的内存。

您可以轻松地创建散列的浅表副本:

my $copy = { %$source };

列表上下文中的%$source位将扩展为键值对列表。花括号(匿名散列构造函数)然后获取该列表,从中创建一个新的hashref。如果您的结构是一维的,或者您不需要克隆任何包含的数据结构,那么浅拷贝就可以了。

要执行完整深层复制,您可以使用核心模块Storable

use Storable 'dclone';

my $deep_copy = dclone $source;

答案 1 :(得分:7)

是的,赋值只是复制引用(就像在其他语言中复制指针值一样)。您正在寻找的东西称为“深层复制品”。

Storable::dclone似乎是一种解决方案(perldoc Storable以获取更多信息)。

Clone是另一个(perldoc clone);感谢Zaid在评论中提到这一点。

答案 2 :(得分:3)

如果它只是一个哈希,你要找的就是它的副本:

my $hashref = {data => "a"};

my %hash_copy = %{$hashref}; # Create a copy of the hash that $hashref points to
my $hashref_copy = \%hash_copy; # Ref to %hash_copy
$hashref_copy->{data} = "b";

print "$hashref->{data}\n"; # Outputs 'a'
print "$hashref_copy->{data}\n"; # Outputs 'b'