golang的map類型是一個比較特殊的類型,不同於int, string, byte這樣的基本類型,在經過一番探究之后得出了一些結論:
1、golang的map類型雖然是內置類型,但和基本類型有很大區別,更像是一個指針,因為他有着跟指針一樣行為。
下面這段代碼的第三次輸出時,嘗試了用通過arr[1].c["aaa"] = "lalala",這種方式去修改這個map元素,發現arr[0]同時被改變了。這也就說明了arr里面保存的其實是指向一塊內存的指針,所以在通過arr[1].c["aaa"] = "lalala"這種方式修改時,arr[0]也同時被修改了。
2、修改arr[1]的時候,同時也修改了int類型的a,但是arr[0]卻沒有同時被更改,這可以說明兩點。
a. append函數在追加arr數組時,傳遞給append函數的參數是一個實體,而不是指針或引用
b. 在拷貝Node實體時,int類型的a是被深拷貝的,也就是拷貝了 一個實體,而map只是被拷貝了指針(扯不清楚,就是那個意思)
綜合以上兩個結論可以得出:我們其實可以把map看成是一個指針對象,這樣就可以防止不正確的使用方式帶來的隱患了
// 定義了一個結構體
type Node struct {
a int
c map[string]string
}
// 定義了一個Node類型的數組
arr := make([]Node, 0)
x := Node{}
x.a = 1
x.c = make(map[string]string, 0)
x.c["aaa"] = "bbb"
arr = append(arr, x) //將一個Node對象追加到 arr 數組
//-------第一次輸出--------//
fmt.Println(arr)
x.a = 3 // 將同一個Node對象修改之后再次追加
x.c["aaa"] = "ccc"
x.c["dlskjfd"] = "dlkfsd"
arr = append(arr, x)
//-------第二次輸出--------//
//-------第二次輸出--------//
fmt.Println(arr)
arr[1].a = 34
arr[1].c["aaa"] = "lalalala"
//-------第三次輸出--------//
//-------第三次輸出--------//
fmt.Println(arr)
運行這段代碼的輸出如下:
[{1 map[aaa:bbb]}]
[{1 map[aaa:ccc dlskjfd:dlkfsd]} {3 map[aaa:ccc dlskjfd:dlkfsd]}]
[{1 map[aaa:lalalala dlskjfd:dlkfsd]} {34 map[aaa:lalalala dlskjfd:dlkfsd]}]