【Go语言】copy函数针对切片操作,底层内存空间的变化

在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
  1. 由于切片是引用数据类型,所以在经过copy操作后,slice2会拷贝一份数据放进slice1引用的数据空间(即arr[:4])会变成[2, 3, 4, 5]。

    这里切片在内存中真正的布局其实并不是这样的,此处是为了看着方便特作简化操作。

  2. 此时数组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函数对内存的处理。

你可能感兴趣的:(【Go语言】copy函数针对切片操作,底层内存空间的变化)