在 C/C++ 中,数组(名)是指针。将数组作为参数传进函数时,相当于传递了数组内存地址的引用,在函数内部会改变该数组的值。
在 Go 中,数组是值。作为参数传进函数时,传递的是数组的原始值拷贝,此时在函数内部是无法更新该数组的。
// 数组使用值拷贝传参
func main() {
x := [3]int{1,2,3}
func(arr [3]int) {
arr[0] = 9
fmt.Println(arr) // [9 2 3]
}(x)
fmt.Println(x) // [1 2 3] // 并不是你以为的 [9 2 3]
}
打印结果:
[9 2 3]
[1 2 3]
想改变数组,直接传递指向这个数组的指针类型:
// 传址会修改原数据
func main() {
x := [3]int{1,2,3}
func(arr *[3]int) {
(*arr)[0] = 9
fmt.Println(arr) // &[9 2 3]
}(&x)
fmt.Println(x) // [9 2 3]
}
打印结果:
&[9 2 3]
[9 2 3]
直接使用 slice:即使函数内部得到的是 slice 的值拷贝,但依旧会更新 slice 的原始数据(底层 array)
// 错误示例
func main() {
x := []string{"a", "b", "c"}
for v := range x {
fmt.Println(v) // 0 1 2
}
}
打印结果:
0
1
2
// 正确示例
func main() {
x := []string{"a", "b", "c"}
for _, v := range x { // 使用 _ 丢弃索引
fmt.Println(v)
}
}
打印结果:
a
b
c