golang対sliceの深いコピーcopy

2090 ワード

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
",nums)//0xc4200181e0 a:=nums[:3] fmt.Print("222---",len(a),cap(a)) fmt.Printf(" %p
",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
",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