前言:關於值類型和引用類型確實是個比較繞的問題,之前在學校的時候學習C語言的時候,就感覺沒有看太懂,后面看java,關於引用也是模模糊糊,這個東西也確實比較抽象,估計好多寫了好幾年代碼的人有也有些迷惑。
1、在go語言中,值類型和引用類型有以下特點:
a、值類型:基本數據類型,int,float,bool,string,以及數組和struct
特點:變量直接存儲值,內存通常在棧中分配,棧在函數調用完會被釋放
b、引用類型:指針,slice,map,chan等都是引用類型
特點:變量存儲的是一個地址,這個地址存儲最終的值。內存通常在堆上分配,通過GC回收。
2、這個的東西總結也不太好描述,還是代碼看得比較清楚,用函數實現交換兩個函數的值,來深刻感受以下值類型和引用類型:
package main
import (
"fmt"
)
//在函數內部修改值,不會影響函數外它的值,int是值類型
func swap1(a, b int) {
temp := a
a = b
b = temp
}
//可以通過返回值,實現交換
func swap2(a, b int) (c, d int) {
c = b
d = a
return c, d
}
//指針是一個地址,值傳遞后,在棧中分配的內存存儲的值是a,b的地址,所以通過指針*a,*b這樣是可以改變值的。
func swap3(a, b *int) {
temp := *a
*a = *b
*b = temp
return
}
// 這樣交換的是兩個表示內存地址的值,也是不會影響函數外邊的值的
func swap4(a, b *int) {
temp := a
a = b
b = temp
}
func main() {
first := 100
second := 200
third := 300
fourth := 400
swap1(first, second)
fmt.Println("first= ", first)
fmt.Println("second= ", second)
three, four := swap2(300, 400)
fmt.Println("third= ", three)
fmt.Println("fourth= ", four)
swap3(&first, &second)
fmt.Println("first= ", first)
fmt.Println("second= ", second)
swap4(&third, &fourth)
fmt.Println("third= ", third)
fmt.Println("fourth= ", fourth)
}
結果執行如下:
first= 100 second= 200 third= 400 fourth= 300 first= 200 second= 100 third= 300 fourth= 400
可能還是比較繞,慢慢理解吧,哈哈~~~
3、關於值傳遞和引用傳遞
值傳遞:值傳遞是指在調用函數時將實際參數復制一份傳遞到函數中,這樣在函數中如果對參數進行修改,將不會影響到實際參數
引用傳遞:所謂引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那么在函數中對參數所進行的修改,將影響到實際參數。最早出現c++中
其實在go語言中,只存在值傳遞,好多人有個誤解,說slice,map,chan這些引用類型是引用傳遞,誤區可能就是:map、slice、channel這類引用類型在傳遞到函數內部,可以在函數內部對它的值進行修改而引起的誤會。
