Perl的浅拷贝和深度拷贝

Posted f-ck-need-u

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Perl的浅拷贝和深度拷贝相关的知识,希望对你有一定的参考价值。

首先是深、浅拷贝的概念:

  • 浅拷贝:shallow copy,只拷贝第一层的数据。Perl中赋值操作就是浅拷贝
  • 深拷贝:deep copy,递归拷贝所有层次的数据,Perl中Clone模块的clone方法,以及Storable的dclone()函数是深拷贝

所谓第一层次,指的是出现嵌套的复杂数据结构时,那些引用指向的数据对象属于深一层次的数据。例如:

@Person1=('wugui','tuner');
@Person2=('longshuai','xiaofang',['wugui','tuner']);
@Person3=('longshuai','xiaofang',@Person1);

@Person1只有一层深度,@Person2@Person3都有两层深度。

当进行赋值时,拷贝给目标的只是第一层数据对象。

@[email protected];
@[email protected];
@[email protected];

拷贝给@Person1_shallow的是整个@Person1数据,它们在结果上完全等价,拷贝给@Person{2,3}_shallow的是@Person{2,3}的第一层数据,也就是两个元素和一个引用,拷贝引用时不会对引用进行递归拷贝给赋值对象。简单地说,浅拷贝的过程就是源数据是怎样的,拷贝后就是怎样的。

如下图:

技术分享图片

因为浅拷贝时引用不会进行递归,所以拷贝前后的两个对象都指向同一个引用。所以修改它们共同引用的数据,同时也会修改另一份数据。例如:

@Person=('longshuai','xiaofang',['wugui','tuner']);
@[email protected];

$Person_shallow[2][1]="fairy";

say "$Person_shallow[2][1]";   # 输出:fairy
say "$Person[2][1]";           # 输出:fairy

上述例子中只是给@Person_shallow进行了元素修改操作,但同时却把原始数据@Person也改了。因为@Person_shallow@Person引用的数据对象是相同的。

为了在拷贝阶段保护引用的数据对象,Perl提供了深拷贝的方式。它会对引用进行递归,拷贝引用所指向的数据对象。如图:

技术分享图片

也就是说,深拷贝的方式使得拷贝前后出现了两个完全独立的、互不影响的数据对象,修改其中任何一个对象都不会影响另一个。

Perl提供了一个Clone包(现在包的概念就是模块),它的clone()可以递归拷贝,也就是深拷贝。Storable模块也提供了dclone()函数进行深拷贝。在拷贝层次低于或等于3层时,Clone()的拷贝速度更快,在层次大于或等于4层时,dclone()速度更快。

需要注意,clone()和dclone()的参数都必须是引用变量,当然,也可以是构建的引用。

例如,使用Clone的clone()方法进行深拷贝:

shell> cpan -i Clone
use 5.010;
use Clone qw(clone);

@Person=('longshuai','xiaofang',['wugui','tuner']);
$Person_deep=clone(@Person);

$Person[2][1]="fairy";

say "$Person[2][1]";         # 输出:fairy
say "$Person_deep->[2][1]";  # 输出:tuner

同样,使用Storable模块的dclone()。

use 5.010;
use Storable qw(dclone);

@Person=('longshuai','xiaofang',['wugui','tuner']);
$Person_deep=dclone(@Person);

$Person[2][1]="fairy";

say "$Person[2][1]";         # 输出:fairy
say "$Person_deep->[2][1]";  # 输出:tuner

关于Storable模块,他是用来实现数据持久化的主要工具,后面会有专门的文章详细介绍。

以上是关于Perl的浅拷贝和深度拷贝的主要内容,如果未能解决你的问题,请参考以下文章

js中对象的浅拷贝和深拷贝的区别

对象的浅拷贝与深拷贝

python中的浅拷贝和深拷贝

Python对象的浅拷贝与深拷贝

js的浅拷贝和深拷贝

C++类的浅拷贝深拷贝以及写时拷贝问题