yes-no 发表于 2018-9-20 11:29:55

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=55
  
fmt.Println(nums,a,b)
  
}
  

  

  发现 nums修改了数据后,其他全部都改变了,并且地址都一样,想了想 到底哪里出了问题呢? 是 copy 的问题?
  

   len cap   address  
111---5 5    0xc4200181e0
  
222---3 5    0xc4200181e0
  
333---3 3    0xc4200181e0
  
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
  

  

  其实研究明白了,都是小问题;
  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


页: [1]
查看完整版本: golang 对slice的深拷贝 copy