60.笔记go语言——Go语言的传参和传引用
go 参数传递:函数参数全部是传值:即使传递的是指针,传递的也是指针的拷贝;闭包引用外部变量是引用
Go语言的函数调用参数全部是传值的, 包括 slice/map/chan 在内所有类型, 没有传引用的说法.
slice不是传引用
代码如下:
packagemain
import(
"fmt"
)
funcmain(){
a:=[]int{1,2,3}
fmt.Println(a)
modifySlice(a)
fmt.Println(a)
}
funcmodifySlice(data[]int){
data=nil
}
执行:
[1 2 3]
[1 2 3]
说明a在调用modifySlice前后并没有任何变化, 因此a必然是传值的!
传指针
代码:
packagemain
import(
"fmt"
)
funcmain(){
a:=new(int)
fmt.Println(a)
modify(a)
fmt.Println(a)
}
funcmodify(a*int){
a=nil
}
执行如下:
0xc0420381d0
0xc0420381d0
函数参数传传指针也是传值的,并不是传引用!
所有类型的函数参数都是传值的!
包括slice/map/chan等基础类型和自定义的类型都是传值的.
但是因为slice和map/chan底层结构的差异, 又导致了它们传值的影响并不完全等同.
Go语言有传引用的说法吗?
Go语言其实也是有传引用的地方的, 但是不是函数的参数, 而是闭包对外部环境是通过引用访问的.
代码如下:
packagemain
import(
"fmt"
)
funcmain(){
a:=new(int)
fmt.Println(a)
func(){
a=nil
}()
fmt.Println(a)
}
执行如下:
0xc0420381d0
<nil>
因为闭包是通过引用的方式使用外部环境的a变量, 因此可以直接修改a的值.
小结
函数参数传值, 闭包传引用!
slice含values/count/capacity 等信息, 是按值传递
按值传递的 slice 只能修改values指向的数据, 其他都不能修改
slice是结构体和指针的混合体
引用类型和传引用是两个概念