go語言---map
阿新 • • 發佈:2018-07-08
field 傳引用 塊存儲 === 聲明 print ann 維護 ava
go語言---map
https://blog.csdn.net/cyk2396/article/details/78890185
一.map的用法:
type PersonDB struct { Id string Name string Address string } fmt.Println("=========Map===========") //map是一堆鍵值對的未排序集合,在golang中是內置類型,可以直接使用,不像Java需要引入HashMap var personMap map[string]PersonDB //聲明一個map變量,string是鍵的類型,PersonDB是值的類型 personMap = make(map[string]PersonDB, 10) //創建一個map,初始容量為10 personMap["1"] = PersonDB{Id: "1", Name: "zs", Address: "北京市房山區"} //給map元素賦值 personMap["2"] = PersonDB{Id: "2", Name: "ls", Address: "北京市海澱區"} //使用內置函數delete刪除personMap中key="1"的元素,如果找不到該key,則什麽也不會發生,如果personMap為nil,則拋錯 delete(personMap, "1") if value, ok := personMap["2"]; ok { //找到key=2的元素,則ok=true,value為找到的值;否則ok=false fmt.Println(value) } personMap2 := map[string]PersonDB{"3": PersonDB{"3", "ww", "杭州市西湖區"}} //創建並初始化一個map personMap2["4"] = PersonDB{"4", "ll", "北京市東城區"} for k, v := range personMap2 { //使用range遍歷map中的元素 fmt.Println(k, v) if k == "3" { v.Name = "wwUpdate" personMap2["3"] = v //可更改value值 //以下這種賦值方式會報錯,只能對value賦值,不能直接更改其成員變量 // personMap2["3"].Name = "wwUpdate" //cannot assign to struct field personMap2["3"].Name in map } } fmt.Println(personMap2)
輸出結果:
fatal error: concurrent map writes
由結果可知:map不是線程安全的。
至於為什麽不是線程安全,以後再分析
三.map傳值還是傳引用?
運行以下代碼:
//map傳值還是傳引用? map和slice,channel一樣,內部都有一個指向真正存儲空間的指針,所以,即使傳參時是對值的復制(傳值),但都指向同一塊存儲空間。 var myMapV map[string]int var myMap1 map[string]int myMapV = map[string]int{"value": 0} myMap1 = myMapV fmt.Println("m =", myMapV) fmt.Println("m1 =", myMap1) myMap1["value"] = 1 fmt.Println("m =", myMapV) fmt.Println("m1 =", myMap1)
二.map是線程安全的嗎?
運行以下代碼:
//map不是線程安全的。 cMap := make(map[string]int) for i := 0; i < 100; i++ { go func() { for j := 0; j < 100; j++ { cMap[fmt.Sprintf("%d", j)] = j //fatal error: concurrent map writes } }() } time.Sleep(3 * time.Second)
輸出結果:
m = map[value:0]
m1 = map[value:0]
m = map[value:1]
m1 = map[value:1]
我們發現,當修改了m1,m也隨著改變了,這看似是傳引用,但其實map也是傳值的,它的原理和數組切片類似。map內部維護著一個指針,該指針指向真正的map存儲空間。我們可以將map描述為如下結構:type map[key]value struct{
impl *Map_K_V
}
type Map_K_V struct{
//......
}
其實,map和slice,channel一樣,內部都有一個指向真正存儲空間的指針,所以,即使傳參時是對值的復制(傳值),但都指向同一塊存儲空間。
go語言---map