传参和传引用问题,在golang 的一些教材中多有描述,现在再温习一遍
所有类型的函数参数都是传值的,包括slice/map/chan等基础类型和自定义的类型
但是因为 slice 和 map/chan 底层结构的差异,又导致了它们传值得影响并不完全等同
归纳如下:
Golang 所有函数参数都是传值的
map/slice/chan 都是传值,不是传引用
map/chan 对应指针,和引用类似
slice是结构体和指针的混合体
slice 含有 values/count/capacity 等信息,是按值传递
slice中的values是指针,按值传递
按值传递的slice 只能修改values指向的数据,其他都不能修改
Golang语言有引用的说法吗?
Golang的语言也是有传引用的地方的,但是不是函数的参数,而是闭包对外部环境是通过引用访问的
coding:
func main() {
a:= new(int)
fmt.Println(a)
func(){ a= nil }()
fmt.Println(a)
}
输出为:
0xc010000000 <nil>
因为闭包是通过引用的方式使用的外部环境的a变量,因此可以直接修改a的值。
闭包的概念、形式与引用 http://www.ibm.com/developerworks/cn/linux/l-cn-closure/index.html
如果不想修改a的值,避免闭包的副作用,回避的办法是通过参数传值或 每次闭包构造不同的临时变量
方法一:
for i:=0; i<5; i++ {
i := i
defer func() {
fmt.Printf(" %d ",i )
}()
}
方法二:
for i:= 0; i<5; i++ {
defer func(i int) {
fmt.Printf("%d ",i)
}(i)
}