美文网首页
深拷贝与浅拷贝

深拷贝与浅拷贝

作者: 牧神_c9dd | 来源:发表于2021-06-27 21:45 被阅读0次

    概念

    golang开发时,我们会经常的把一个变量赋值给另一个变量,这个过程可能发生深拷贝也可能发生浅拷贝,二者有什么区别和联系呢?
    

    1、深拷贝(Deep Copy)

    深拷贝,拷贝的是数据本身,创造一个新对象,新创建的对象与原对象不共享内存,新创建的对象在内存中开辟一个新的内存地址,新对象值修改时不会影响原对象值。既然内存地址不同,释放内存地址时,可分别释放。
    
    值类型的数据,默认全部都是深拷贝,Array、Int、String、Struct、Float,Bool。
    
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        a := [3]int{1,2,3}
        b := a  //深拷贝
        b[0] = 4 //修改数组b的值,不影响数组a
        fmt.Println(a,b) //[1 2 3] [4 2 3]
    }
    

    2、浅拷贝(Shallow Copy)

    浅拷贝,拷贝的是数据地址,只复制指向的对象的指针,此时新对象和老对象指向的内存地址是一样的,新对象值修改时老对象也会变化。释放内存地址时,同时释放内存地址。
    
    引用类型的数据,默认全部都是浅拷贝,Slice,Map。
    
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        a := []int{1,2,3}   //定义一个切片
        b := a  //浅拷贝
        b[0] = 4    //修改b的值,a的值也会跟着变
        fmt.Println(a,b)    //[4 2 3] [4 2 3]
        
        //map同样也是浅拷贝
        c := map[string]int {"柯南":98,"lufy":75,"naruto":86}
        d := c
        d["lufy"] = 88
        fmt.Println(c,d)    //map[lufy:88 naruto:86 柯南:98] map[lufy:88 naruto:86 柯南:98]
    }
    
    

    区别

    深拷贝和浅拷贝的本质区别,在于是否真正获取(复制)对象实体,而不是仅仅引用。
    

    扩容摆脱同根

    从上述例子看出来,slice若不是深拷贝,或者重新生成新空间,无论通过参数传递还是使用 := 或者 [:]赋值都存在同根性。    
    
    而扩容可以摆脱这种同根性。
    
    Slice与Array最大的区别在于Slice不需要指定大小会自动扩容等一些特性,Slice在多次append元素时,若满足扩容策略,这时候内部就会重新申请一块内存空间,将原本的元素拷贝一份到新的内存空间上。此时其与原本的数组就没有任何关联关系了,再进行修改值也不会变动到原始数组。
    
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        a := []int{1,2,3}   //定义一个切片
        b := a[0:1]     
        for i:=0;i<=6;i++{
            b = append(b,i) //容量未满时是浅拷贝,一旦扩容就是深拷贝了
        }
        b[0] = 10   //验证
        fmt.Println(a,b)    //[1 0 1] [10 0 1 2 3 4 5 6]
        
    }
    

    相关文章

      网友评论

          本文标题:深拷贝与浅拷贝

          本文链接:https://www.haomeiwen.com/subject/ixqfultx.html