13.1 Go语言的深拷贝和浅拷贝 - Go语言中文社区

13.1 Go语言的深拷贝和浅拷贝


深浅拷贝

在很多编程语言都有深浅拷贝的这个概念,当然golang也不例外,在go语言中值类型赋值都是深拷贝,引用类型一般都是浅拷贝,其本质就是,深拷贝会拷贝数据,而浅拷贝只会拷贝内存的地址,所有就会出现,像slice那样修改底层数组的值,slice的值也跟着改动。

int、string、struct等是值类型,默认是深拷贝。指针、map、slice、chan等这些是引用类型,默认是浅拷贝。

深拷贝

修改a的值b不变,说明是值的拷贝,

  1. func main() {
  2. var a = 123
  3. b := a
  4. fmt.Println(a, b)
  5. a = 456
  6. fmt.Println(a, b)
  7. }

浅拷贝

修改a的值,b的值也跟着修改了,原因是两个slice指向同一个内存地址,所以得出记录slice拷贝是浅拷贝

  1. func main() {
  2. a := []int{1, 2, 3}
  3. b := a
  4. fmt.Println(a, b)
  5. a[0] = 1000
  6. fmt.Println(a, b)
  7. }

slice实现深拷贝

可以通过内置的copy函数实现,也可以使用append生成一个新的。

append函数
  1. func main() {
  2. a := []int{1, 2, 3}
  3. b := make([]int, 0)
  4. b = append(b, a[:]...)
  5. fmt.Println(a, b)
  6. a[1] = 1000
  7. fmt.Println(a, b)
  8. fmt.Printf("%p,%p", a, b)
  9. }
copy函数

需要注意的是copy函数不会扩容,也就是要复制的slice比原slice要大的时候,只会把容量占满多余的移除。

  1. func main() {
  2. slice1 := []int{1, 2, 3, 4, 5}
  3. slice2 := []int{5, 4, 3}
  4. copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中
  5. fmt.Println(slice1, slice2)
  6. copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置
  7. fmt.Println(slice1, slice2)
  8. }
版权声明:本教程内容除了本站原创内容外,还有来源自C语言编程网,博客园,CSDN等技术站点,感谢相关博主原创文章,转载请附上原文出处链接和本声明。
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 阅读 ( 612 )
  • 分类:Go

0 条评论

官方社群

GO教程

猜你喜欢