GO引用类型和指针
切片是一个引用类型,将它作为参数传入函数后,你在函数里对数据作变更是会实时反映到实参切片的。
func foo(s []int) {
s[0] = 666
}
func main() {
slice := []int{1,2}
fmt.Println(slice) // [1 2]
foo(slice)
fmt.Println(slice) // [666 2]
}
这是因为当你对一个切片 append 的时候,它会做这些事情:
- 新建一个新的切片 slice2,其实长度与 slice1 一样,但容量是 slice1 的两倍,此时 slice2 底层指向的匿名数组和 slice1 不是同一个。
- 将 slice1 底层的数组的元素,一个一个的拷贝给 slice2 底层的数组。
- 并把扩容的元素也拷贝到 slice2中
- 最后把新的 slice2 返回回来,这就是为什么指针不用返回,而 slice.append 也要返回的原因
从这个流程中,可以看到等号左边的 s (slice2)和 等号右边的 s (slice1)底层引用的数组已经不是同一个了
因此切片的形参做扩容,并不会影响到实参。
坚冰还盖着北海的时候,我看到了怒放的梅花。

浙公网安备 33010602011771号