測試 slice的地址 copy的時候 發現有問題:golang
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 的問題?c#
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的
修改成:google
var b =make([]int,len(nums[:3:3]))
再進行copy 結果就如語氣了,b的值不會被修改了。spa
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]
其實研究明白了,都是小問題;code
golang深拷貝任意結構代碼:對象
```blog
// 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文檔