由Insert引出的slice底层存储问题
其实这个只是在搜索对go中的slice进行插入时,一行代码引起的小实验。
结论:对slice的修改是直接体现于底层内存中的
现在想尝试对数组指定位插入一个值。所以先声明数组:
arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
现在尝试对下标第 2 位插入-1
,在网上看到一种方式如下(为了方便,对每一步操作的数组进行打印输出):
tmp := append([]int{}, arr[2:]...)
fmt.Printf("tmp: %v\n", tmp)
arr = append(arr[0:2], -1)
fmt.Printf("arr: %v\n", arr)
fmt.Printf("tmp: %v\n", tmp)
arr = append(arr, tmp...)
fmt.Printf("arr: %v\n", arr)
按照上述代码确实可以达成我们的目的,最终添加的输出代码打印结果如下:
tmp: [3 4 5 6 7 8 9 0]
arr: [1 2 -1]
tmp: [3 4 5 6 7 8 9 0]
arr: [1 2 -1 3 4 5 6 7 8 9 0]
所以问题来了,是否可以将代码中对 tmp
的赋值,由 append
这种拷贝一个新数组的方式,改为直接引用原 slice 呢?
为了解答这个问题,继续试验,修改原代码如下:
tmp := arr[2:] // append([]int{}, arr[2:]...)
fmt.Printf("tmp: %v\n", tmp)
arr = append(arr[0:2], -1)
fmt.Printf("arr: %v\n", arr)
fmt.Printf("tmp: %v\n", tmp)
arr = append(arr, tmp...)
fmt.Printf("arr: %v\n", arr)
这次的输出就可以说明问题了:
tmp: [3 4 5 6 7 8 9 0]
arr: [1 2 -1]
tmp: [-1 4 5 6 7 8 9 0]
arr: [1 2 -1 -1 4 5 6 7 8 9 0]
由于 tmp
直接引用的是 arr
,所以当 arr
的第 2 位修改之后,tmp
的第 0 位也随即发生更改,所以才会出现最后的这个结果。
所以实践表明,对于 slice 内容的修改,也可能会使其他直接引用了的 slice 内容发生变化,毕竟他们使用的是同一块内存。所以最稳妥的办法自然是拷贝一份新的再添加回来了。
网友评论