写在前面
很多人对数组和切片以及函数参数理解不够深刻。今天就来讲一讲
数组和切片
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]
}
总结
本文考察的是对数组、切片、函数参数的理解