返回

Slice作为函数参数,你注意到了吗?

后端

前言

Go语言中,slice是一种动态数组,它可以存储相同类型的值。slice作为函数参数时,传递的是引用,这意味着对slice的修改会影响到函数外部的slice。这在某些情况下是需要的,但在其他情况下可能导致意想不到的错误。

slice作为函数参数的陷阱

slice作为函数参数时,最常见的陷阱之一是意外修改了函数外部的slice。例如,以下代码将导致函数外部的slice被意外修改:

func modifySlice(slice []int) {
  slice[0] = 10
}

func main() {
  slice := []int{1, 2, 3}
  modifySlice(slice)
  fmt.Println(slice) // 输出:[10 2 3]
}

在这个例子中,modifySlice函数接收一个slice作为参数,并修改了slice的第一个元素。因为slice是引用传递的,所以对slice的修改也会影响到函数外部的slice。

如何避免意外修改slice

为了避免意外修改slice,可以采用以下几种方法:

  • 使用值传递而不是引用传递。例如,以下代码将使用值传递的方式将slice传递给modifySlice函数:
func modifySlice(slice []int) {
  slice = append(slice, 10)
}

func main() {
  slice := []int{1, 2, 3}
  modifySlice(slice)
  fmt.Println(slice) // 输出:[1 2 3]
}

在这个例子中,modifySlice函数接收一个slice作为参数,但它使用append函数创建了一个新的slice,而不是修改原有的slice。因此,对新slice的修改不会影响到函数外部的slice。

  • 使用副本而不是原始slice。例如,以下代码将使用副本的方式将slice传递给modifySlice函数:
func modifySlice(slice []int) {
  slice[0] = 10
}

func main() {
  slice := []int{1, 2, 3}
  modifySlice(slice)
  fmt.Println(slice) // 输出:[1 2 3]
}

在这个例子中,modifySlice函数接收一个slice副本作为参数,而不是原始slice。因此,对slice副本的修改不会影响到函数外部的slice。

总结

slice作为函数参数时,传递的是引用,这意味着对slice的修改会影响到函数外部的slice。为了避免意外修改slice,可以采用值传递或副本的方式将slice传递给函数。