GO 函数内部能改变数组元素吗


写在前面

很多人对数组和切片以及函数参数理解不够深刻。今天就来讲一讲

数组和切片

go中数组类型包括元素数量,即 [1]int,[2]int,[3]int这是3个不同的数据类型。

切面底层是指向一个数组的结构体,并且数组的大小、地址可能会发生变化。切面定义如下:

type Slice struct{
    ptr 
    len int
    cap int
}

所以可以把切片理解成一个结构体。

函数参数

go 中所有的函传参都是值传递,不是引用传递,即把原来变量的值拷贝一份传递到函数中。

func main() {
	x := [3]int{1, 2, 3}

	func(arr [3]int) {
		arr[0] = 7
		fmt.Println(arr) // [7 2 3]
	}(x)
	fmt.Println(x) // [1 2 3] // 并不是你以为的 [7 2 3]
}

数组x传到函数中后,attr是x的一个复制,修改attr并不会影响外层x的值。因为x的类型是数组[3]int

如何在函数内部改变数组元素

传递数组指针到函数


func main() {
	x := [3]int{1, 2, 3}

	func(arr *[3]int) {
		(*arr)[0] = 7
		fmt.Println(arr) // &[7 2 3]
	}(&x)
	fmt.Println(x) // [7 2 3]
}

使用切片

切片虽然也是值拷贝,但是它拷贝的是切片这个结构体的值,在函数内部修改切片内容会修改对于数组的内容。原始切片和拷贝后的切面虽然地址不一样,但是指向的数组地址是相同的

func main() {
	x := []int{1, 2, 3}

	func(arr []int) {
		arr[0] = 7
		fmt.Println(arr) // [7 2 3]
	}(x)
	fmt.Println(x) // [1 2 3] // 并不是你以为的 [7 2 3]
}

总结

本文考察的是对数组、切片、函数参数的理解


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录