按理说,go函数传参都是值传递,但是某些情况也是能修改原值的,修改的方式与我想象中的又有些区别特此记录。
func testArraParam(v []int) {
fmt.Printf("before testArraParam=%v,%p\n", v, &v)
v[1] = 7 //修改数据
v = append(v, 4, 5, 6) //添加数据
fmt.Printf("after testArraParam=%v,%p\n", v, &v)
}
func main(){
arra1 := make([]int, 0) //创建一个切片
fmt.Printf("append arra=%v,%p\n", arra1, &arra1)
arra1 = append(arra1, 1, 2, 3) //增加元素
fmt.Printf("before arra=%v,%p\n", arra1, &arra1)
testArraParam(arra1)
fmt.Printf("after arra=%v,%p\n", arra1, &arra1)
}
实际结果输出:
append arra=[],0xc0000044e0
before arra=[1 2 3],0xc0000044e0
before testArraParam=[1 2 3],0xc000004540
after testArraParam=[1 7 3 4 5 6],0xc000004540
after arra=[1 7 3],0xc0000044e0
从结果看,函数里的 v[1] = 7
生效了。。但好像又不是那么简单,因为后面的append操作没有影响到原来的切片。
从指针地址
上看的话,函数里的v参数
跟原切片
地址确实不是同一个,感觉有点类似c++中的别名,但是又有些区别。如果是别名append
就会修改原值。这点在日常go使用中需要注意一下。
如果要想函数中的append
生效的话,我们需要传递指针
func testArraParam2(v *[]int) {
fmt.Printf("before testArraParam2=%v,%p\n", *v, v)
(*v)[1] = 7 //修改数据
*v = append(*v, 4, 5, 6) //添加数据
fmt.Printf("after testArraParam2=%v,%p\n", *v, v)
}
//调用方式
/*
testArraParam2(&arra1)
fmt.Printf("after testArraParam2 arra=%v,%p\n", arra1, &arra1)
*/
打印结果
append arra=[],0xc00011c460
before arra=[1 2 3],0xc00011c460
before testArraParam=[1 2 3],0xc00011c4c0
after testArraParam=[1 7 3 4 5 6],0xc00011c4c0
after arra=[1 7 3],0xc00011c460
before testArraParam2=[1 7 3],0xc00011c460
after testArraParam2=[1 7 3 4 5 6],0xc00011c460
after testArraParam2 arra=[1 7 3 4 5 6],0xc00011c460