1、golang值類型與引用類型的區別
1.1 本質存儲區別
值類型與引用類型的區別主要在於:
- 值類型的變量: 存儲當前類型的存儲的數據。值類型包括數值類型、bool、string、數組、struct結構體
- 引用類型的變量:存儲地址,該地址對應的空間纔是真正存儲的數據。引用類型包括:指針、slice切片、管道chan、map、以及interface等類型。
注意:golang中的引用類型和值類型的區別與C++中的指針類型和值類型的區別類似。而C++中的引用類型與golang中的引用類型不是同一個概念。
1.2 使用區別
- 值類型:聲明變量之後可以直接使用
- 引用類型:對於引用類型,若使用var進行聲明變量,必須使用make函數對其進行分配內存。若不初始化,該變量默認值爲nil,向其添加元素時會導致panic。
2、示例驗證
我們可以通過下面的小程序來驗證上述的想法:
- 對於int類型的a,將其轉換爲地址進行打印,結果打印表示錯誤類型,不是地址類型.a:%!p
- 對於map類型b,將其轉換爲地址打印可看出其存儲的爲指針類型且爲0xc000078150,將其傳入函數中,該函數接受的參數值也爲該變量存儲的地址值test:0xc000078150。
package main
import "fmt"
func test(test map[string]string) {
// test:0xc000078150
fmt.Printf("test:%p\n", test)
// &test:0xc000098028
fmt.Printf("&test:%p\n", &test)
}
func main() {
a := 10
// a:%!p(int=10)
fmt.Printf("a:%p\n", a)
// &a:0xc000096010
fmt.Printf("&a:%p\n", &a)
b := map[string]string{}
// b:0xc000078150
fmt.Printf("b:%p\n", b)
// &b:0xc000098020
fmt.Printf("&b:%p\n", &b)
test(b)
}