zoukankan      html  css  js  c++  java
  • 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都有两层深度。

    浅拷贝

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

    @Person1_shallow=@Person1;
    @Person2_shallow=@Person2;
    @Person3_shallow=@Person3;
    

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

    如下图:

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

    @Person=('longshuai','xiaofang',['wugui','tuner']);
    @Person_shallow=@Person;
    
    $Person_shallow[2][1]="fairy";
    
    say "$Person_shallow[2][1]";   # 输出:fairy
    say "$Person[2][1]";           # 输出:fairy
    

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

    深拷贝:Clone和Storable

    为了在拷贝阶段保护引用的数据对象,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模块,他是用来实现数据持久化的主要工具,后面会有专门的文章详细介绍。

  • 相关阅读:
    Hibernate save, saveOrUpdate, persist, merge, update 区别
    Eclipse下maven使用嵌入式(Embedded)Neo4j创建Hello World项目
    Neo4j批量插入(Batch Insertion)
    嵌入式(Embedded)Neo4j数据库访问方法
    Neo4j 查询已经创建的索引与约束
    Neo4j 两种索引Legacy Index与Schema Index区别
    spring data jpa hibernate jpa 三者之间的关系
    maven web project打包为war包,目录结构的变化
    创建一个maven web project
    Linux下部署solrCloud
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9721265.html
Copyright © 2011-2022 走看看