在go语言中,copy函数针对切片进行复制操作,在底层中,内存空间可以互相重叠,也可以相互独立。
首先讲一下数据空间相互重叠的情况:
1 var arr = [5]int {1,2,3,4,5}
2 var slice1 []int = arr[:4] // 1 2 3 4
3 var slice2 []int = arr[1:] // 2 3 4 5
4 copy(slice1, slice2) // 将slice2复制到slice1中
5 fmt.Println(arr) // 2 3 4 5 5
6 fmt.Println(slice1) // 2 3 4 5
7 fmt.Println(slice2) // 3 4 5 5
-
由于切片是引用数据类型,所以在经过copy操作后,slice2会拷贝一份数据放进slice1引用的数据空间(即arr[:4])会变成[2, 3, 4, 5]。
此时数组arr中的值变成了[2, 3, 4, 5, 5],倘若我们对数组进行arr[1] = 100的操作,由于slice1和slice2引用的是同一个数据空间,所以slice1和slice2中的元素都会发生改变。
数据空间相互独立的情况:
1 var slice3 = []int{1, 2, 3, 4, 5} // 1 2 3 4 5
2 var slice4 = make([]int, 10) // 默认值 0 0 0 0 0 0 0 0 0 0 0
3 copy(slice4, slice3)
4 slice3[0] = 100 // 只改变slice3的数据
5 fmt.Println(slice3) // 100 2 3 4 5
6 fmt.Println(slice4) // 1 2 3 4 5 0 0 0 0 0
slice3和slice4引用的是不同数据空间,copy函数只是将slice3中的数据拷贝一份放入slice4所引用的空间中,两者的内存空间是相互独立的。因此,当我们修改slice3中的数据时,slice4不会发生改变。
总结:1.copy函数是拷贝值,而不是修改切片的引用;2.切片是引用数据类型。
由于本人技术有限,在原理方面可能讲得并不是太透彻,不过相信各位读者通过自己敲打代码,也可以了解copy函数对内存的处理。