在很多编程语言都有深浅拷贝的这个概念,当然golang也不例外i,在go语言中值类型赋值都是深拷贝,引用类型一般都是浅拷贝,其本质就是,深拷贝会拷贝数据,而浅拷贝只会拷贝内存的地址,所有就会出现,像slice那样修改底层数组的值,slice的值也跟着改动。
深拷贝
修改a的值b不变,说明是值的拷贝,
func main() { var a = 123 b := a fmt.Println(a, b) a = 456 fmt.Println(a, b) }
浅拷贝
修改a的值,b的值也跟着修改了,原因是两个slice指向同一个内存地址,所以得出记录slice拷贝是浅拷贝
func main() { a := []int{1, 2, 3} b := a fmt.Println(a, b) a[0] = 1000 fmt.Println(a, b) }
slice深拷贝
可以通过内置的copy函数实现,也可以使用append生成一个新的
func main() { a := []int{1, 2, 3} b := make([]int, 0) b = append(b, a[:]...) fmt.Println(a, b) a[1] = 1000 fmt.Println(a, b) fmt.Printf("%p,%p", a, b) }
copy函数
需要注意的是copy函数不会扩容,也就是要复制的slice比原slice要大的时候,只会把容量占满多余的移除。
func main() { slice1 := []int{1, 2, 3, 4, 5} slice2 := []int{5, 4, 3} copy(slice2, slice1) // 只会复制slice1的前3个元素到slice2中 fmt.Println(slice1, slice2) copy(slice1, slice2) // 只会复制slice2的3个元素到slice1的前3个位置 fmt.Println(slice1, slice2) }