golang 對slice的深拷貝 copy


測試 slice的地址 copy的時候 發現有問題:

package main

import "fmt"

func main() {
    nums:=[]int{1,2,3,4,5}
    fmt.Println("     len cap   address")
    fmt.Print("111---",len(nums),cap(nums))
    fmt.Printf("    %p\n",nums)//0xc4200181e0
    a:=nums[:3]
    fmt.Print("222---",len(a),cap(a))
    fmt.Printf("    %p\n",a)//0xc4200181e0 一樣
    //output: 222--- 3 5

    b:=nums[:3:3] //第二個冒號 設置cap的
    n:=copy(b,nums[:3:3]) //第二個冒號 設置cap的
    fmt.Print("333---",len(b),cap(b))
    fmt.Printf("    %p\n",b)//0xc4200181e0 一樣
    //output: 333--- 3 3
    fmt.Println(n,b)
    nums[0]=55
    fmt.Println(nums,a,b)
}

  發現 nums[0]修改了數據后,其他全部都改變了,並且地址都一樣,想了想 到底哪里出了問題呢? 是 copy 的問題?

     len cap   address
111---5 5    0xc4200181e0
222---3 5    0xc4200181e0
333---3 3    0xc4200181e0
3 [1 2 3]
[55 2 3 4 5] [55 2 3] [55 2 3]

 

琢磨了一下,發現 原來是copy前的對象 沒有分配內存,使用了一樣的內存地址導致的,把上文的

 b:=nums[:3:3] //第二個冒號 設置cap的

  修改為:

    var b =make([]int,len(nums[:3:3]))

  再進行copy 結果就如語氣了,b的值不會被修改了。

     len cap   address
111---5 5    0xc4200181e0
222---3 5    0xc4200181e0
333---3 3    0xc42000a400
3 [1 2 3]
[55 2 3 4 5] [55 2 3] [1 2 3]

其實研究明白了,都是小問題;

 

golang深拷貝任意結構代碼:

```

// Clone 完整復制數據
func Clone(a, b interface{}) error {
    buff := new(bytes.Buffer)
    enc := gob.NewEncoder(buff)
    dec := gob.NewDecoder(buff)
    if err := enc.Encode(a); err != nil {
        return err
    }
    if err := dec.Decode(b); err != nil {
        return err
    }
    return nil
}

  

```

參考文檔:

https://golang.google.cn/ref/spec#Appending_and_copying_slices

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM