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 的时候,它会做这些事情:

  1. 新建一个新的切片 slice2,其实长度与 slice1 一样,但容量是 slice1 的两倍,此时 slice2 底层指向的匿名数组和 slice1 不是同一个。
  2. 将 slice1 底层的数组的元素,一个一个的拷贝给 slice2 底层的数组。
  3. 并把扩容的元素也拷贝到 slice2中
  4. 最后把新的 slice2 返回回来,这就是为什么指针不用返回,而 slice.append 也要返回的原因

从这个流程中,可以看到等号左边的 s (slice2)和 等号右边的 s (slice1)底层引用的数组已经不是同一个了

因此切片的形参做扩容,并不会影响到实参。

posted @ 2025-05-30 12:49  Zero&&One  阅读(7)  评论(0)    收藏  举报