如何在Perl中实现数据结构的深拷贝?

41

在给定一个数据结构(例如哈希的哈希)时,有哪些清晰/推荐的方法可以进行深度复制以供立即使用?假设合理情况下,数据不是特别大,不存在复杂的循环,并且可读性/可维护性等比速度更重要。

我知道可以使用StorableClone、Clone::More、Clone::FastData::Dumper等工具。目前的最佳实践是什么?


“[tag:deep-copy]” 真的无关紧要吗,@JasonMArcher?摘要谈到了 C 和 C++,但浅拷贝和深拷贝是与语言无关的概念。通常情况下,“克隆”指的是浅拷贝(Java、C#等),而这个问题要求进行深拷贝。 - Palec
我们的标签不需要深入细节。这些都是各种克隆操作。目前我们有[clone],[cloning],[copy],[deepclone],[deep-clone],[deep]+[clone],[deep]+[copy]和[deep-copy]。 - JasonMArcher
5个回答

19

CloneStorable::dclone快得多,但后者支持更多的数据类型。

Clone::FastClone::More如果我没记错的话基本上是等效的,但比甚至比Clone还不完整,而Scalar::Util::Clone支持的功能更少,但对于某些结构来说是最快的。

就可读性而言,它们应该都可以正常工作,几乎可以互换使用。

如果您没有特定的性能需求,我建议只使用Storable的dclone。

我不会使用Data::Dumper,因为它太繁琐了。它可能也会非常慢。

值得一提的是,如果您需要可定制的克隆,则Data::Visitor提供了挂钩功能,并且相当完整的深度克隆是默认行为。


2
你有Scalar :: Util :: Clone的链接吗?我在CPAN或Metacpan上都找不到它... - Peter V. Mørch

16

我的印象是Storable::dclone()有些经典。


7

Clone 可能是你所需要的。至少,这是我所见到的所有代码都在使用的。


0
尝试使用Panda :: Lib中的fclone,它似乎是最快的(用XS编写)。

CloneStorable都是用XS编写的。你所说的“似乎是最快的”,是什么意思? - melpomene
Panda::Lib 不支持 Windows 系统下的编译,这限制了它的实用性。 - melpomene
1
请查看以下网址中的基准测试结果:https://gist.github.com/jef-sure/ef8849e6abbeb9b8aac74c71389886f7 - Ivan Baidakou
如果你需要让它在Windows上运行,请尝试提交一个错误报告。据我所知,它正在积极维护中。 - Ivan Baidakou

-1

如果你已经在处理JSON并在代码中使用JSON模块,那么可以采用快速而不太规范的方法:将结构转换为JSON,然后将JSON转换回结构:

use JSON;

my %hash = (
    obj => {},
    arr => []
);

my $hash_ref_to_hash_copy = from_json(to_json(\%hash));


唯一的负面可能是必须处理哈希引用而不是纯哈希,但是,对我来说,这有时很方便。

1
JSON序列化的主要限制因素是它无法处理blessed引用(或者类必须以某种方式处理序列化)。如果blessed引用不是数据的一部分,那么这可能没问题。 - brian d foy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接