Go 函数中使用append修改传入的slice为何无效?

我们都知道在 Go 中明确表示没有传引用,所有的函数参数都是传值。而像 map、chan、slice 这些引用类型,虽然是传值,但在函数内亦可以修改其值,达到传引用的效果

但在执行如下代码时,会发现跟预想的结果不一样:

func Change(slice []int) {
    slice = append(slice, 1)
}
func main() {
    slice := []int{}
    Change(slice)
    fmt.Println(slice)
}

执行后会发现,slice 仍旧是空的切片,其原因是: 如果切片的当前大小不足以附加新值,那么切片需要动态增长,从而更改了基础数组。如果没有返回此新切片,那么追加的更改是不生效的。

其解决办法有两种:

  • 直接 return 返回新切片
func Change(slice []int) []int {
    slice = append(slice, 1)
    return slice
}
func main() {
    slice := []int{}
    slice = Change(slice)
    fmt.Println(slice)
}
  • 使用切片指针作为参数
func Change(slice *[]int) {
    *slice = append(*slice, 1)
}
func main() {
    slice := []int{}
    Change(&slice)
    fmt.Println(slice)
}

276 Words

2020-04-11 08:00 +0800