傳參和傳引用問題,在golang 的一些教材中多有描述,現在再溫習一遍
Golang的函數調用參數全部是傳值得,包括 slice/map/chan 在內的所有類型,沒有傳引用的說法
所有類型的函數參數都是傳值的,包括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)
}
總結:
函數參數傳值,閉包傳引用
map、chan 本身是指針,近似於引用傳遞
slice 含有 values/count/capacity 等信息,是按值傳遞
按值傳遞的 slice 只能修改values指向的數據
slice是結構體和指針的混合體