比較熟悉 Python 的對於字典肯定不會陌生,在 Go 中 map 就是 Python 中字典的概念,它的基本格式是
map[keyType]valueType 。map 的讀取和設置和 slice 比較相似,只不過 map 中是通過 key 操作,而 slice
是通過 index 操作,index 只能是 int 類型,map 的 key 可以是 int 、string等類型。
字典的賦值方式
1.先聲明再初始化最后賦值
package main import "fmt" func main() { // 先聲明一個字典,key類型為string value類型為string var m1 map[string]string // 只聲明不賦值的map,零值為nil,此時不能給map賦值 if m1 == nil { // 使用 make 函數對map初始化 m1 = make(map[string]string) } if m1 != nil { // 輸出 map[] fmt.Println(m1) // 賦值操作 m1["name"] = "xiaoming" fmt.Println(m1) } }
輸出結果
[root@VM_81_181_centos golang]# go run map01.go map[] map[name:xiaoming]
2.使用 make 初始化之后再賦值
package main import "fmt" func main() { // 使用 make 直接初始化 m1 := make(map[string]int) m1["age"] = 23 fmt.Println(m1) }
輸出結果
[root@VM_81_181_centos golang]# go run map02.go map[age:23]
3.直接初始化賦值
package main import "fmt" func main() { m1 := map[string]string{ "name":"xiaoming", "hobby":"football", } fmt.Println(m1) }
輸出結果
[root@VM_81_181_centos golang]# go run map03.go map[name:xiaoming hobby:football]
字典的遍歷
字典遍歷提供了兩種方式,一種是需要攜帶 value,另一種是只需要 key,需要使用 range 關鍵字
package main import "fmt" func main() { fruits := map[string]int{ "apple":2, "banana":5, "orange":8, } // 需要攜帶 value for name,score := range fruits{ fmt.Println(name, score) } // 只需要key for name := range fruits{ fmt.Println(name) } }
輸出結果
[root@VM_81_181_centos golang]# go run map04.go apple 2 banana 5 orange 8 ######### apple banana orange
在 Go 中沒有提供類似 keys() 和 values() 這樣的方法,如果我們想獲取 key 和 value 的列表需要自己循環
package main import "fmt" func main() { fruits := map[string]int{ "apple":2, "banana":5, "orange":8, } names := make([]string,0,len(fruits)) scores := make([]int,0,len(fruits)) for name,score := range fruits{ names = append(names,name) scores = append(scores,score) } fmt.Println(names,scores) }
輸出結果
[root@VM_81_181_centos golang]# go run map05.go [apple banana orange] [2 5 8]
字典的讀寫
package main import "fmt" func main() { fruits := map[string]int { "apple": 2, "banana": 5, "orange": 8, } // 讀 fmt.Println(fruits["apple"]) // 增加或修改 fruits["pear"] = 9 fmt.Println(fruits) // 刪除 delete(fruits, "pear") fmt.Println(fruits) }
輸出結果
[root@VM_81_181_centos golang]# go run map08.go 2 map[banana:5 orange:8 pear:9 apple:2] map[apple:2 banana:5 orange:8]
字典的多態返回值
在上面的實例中已經可以知道通過 val1 = map1[key1] 的方法獲取 key1 對應的值 val1。如果 map 中不存在 key1,
val1 就是一個值類型的空值。那么,此時就會出現一個問題 key1 是不存在還是 key1 對應的值就是空值?
下面介紹一種方式判斷 map 中 key 是否存在: val1 , isPresent = map1[key1] ,isPresent 返回一個 bool 值:如果
key1 存在,val1 就是 key1 對應的 value 值,並且 isPresent 為 true;如果 key1 不存在,val1 就是一個空值,並且 isPresent
返回 false。
如果只是想判斷某個 key 是否存在而不關心它對應的值到底是多少,可以這樣做:
_,ok = map1[key1]// 如果 key1 存在,ok == true 否在 ok == false
或者和 if 混合使用
if _,ok := map1[key1];ok { //.... }
從 map1 中刪除 key1,直接 delete(map1,key1),如果 key1 不存在,該操作也不會報錯
package main import "fmt" func main() { map1 := make(map[string]int) map1["New Delhi"] = 55 map1["Beijing"] = 20 map1["Washington"] = 25 value,isPresent := map1["Beijing"] if isPresent { fmt.Printf("The value of \"Beijin\" in map1 is: %d\n", value) } else { fmt.Printf("map1 does not contain Beijing") } // 刪除元素 delete(map1,"Washington") value,isPresent = map1["Washington"] if isPresent { fmt.Printf("The value of \"Washington\" in map1 is: %d\n", value) } else { fmt.Println("map1 does not contain Washington") } }
輸出結果
[root@VM_81_181_centos golang]# go run map09.go The value of "Beijin" in map1 is: 20 map1 does not contain Washington [root@VM_81_181_centos golang]#
字典的排序
字典默認是無序的,如果想要為 map 排序,需要將 key (或者value) 拷貝至一個切片中,再對切片排序,然后可以使用
切片的 for-range 方法打印所有的 key 和 value
package main import ( "fmt" "sort" ) func main() { barVal := map[string]int{ "alpha": 34, "bravo": 56, "charlie": 23, "delta": 87, "echo": 56, "foxtrot": 12, "golf": 34, "hotel": 16, "indio": 87, "juliet": 65, "kili": 43, "lima": 98, } fmt.Println("unsorted:") for key,value := range barVal{ fmt.Printf("Key: %v, Value: %v / ", key, value) } // 創建切片 keys := make([]string,len(barVal)) i := 0 for k,_ := range barVal{ keys[i] = k i++ } sort.Strings(keys) fmt.Println("sorted") for _,k := range keys{ fmt.Printf("Key: %v, Value: %v / ", k, barVal[k]) } }
輸出結果
unsorted: Key: kili, Value: 43 / Key: alpha, Value: 34 / Key: foxtrot, Value: 12 / Key: hotel, Value: 16 / Key: echo, Value: 56 / Key: golf, Value: 34 / Key: indio, Value: 87 / Key: juliet, Value: 65 / Key: lima, Value: 98 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / sorted Key: alpha, Value: 34 / Key: bravo, Value: 56 / Key: charlie, Value: 23 / Key: delta, Value: 87 / Key: echo, Value: 56 / Key: foxtrot, Value: 12 / Key: golf, Value: 34 / Key: hotel, Value: 16 / Key: indi o, Value: 87 / Key: juliet, Value: 65 / Key: kili, Value: 43 / Key: lima, Value: 98 /
字典的鍵值對調
這里的鍵值對調是指調換 key 和 value ,首先能想到的方法就是構造另一個以原 map 的 key 作為 value,以原 map
的 value 作為 key 的 map,然后使用 for-range 遍歷原 map 並導入新 map
package main import "fmt" func main() { originMap := map[string]int{ "a":0, "b":0, "c":2, } fmt.Println(originMap) newMap := make(map[int]string) for key,value := range originMap{ newMap[value] = key } fmt.Println(newMap) }
輸出結果
map[a:0 b:0 c:2] map[2:c 0:b]
看輸出結果,會發現上面的代碼有一個大問題,如果原 map 的 value 不唯一,就會導致新 map 無法完全包含原 map 的
鍵值對,對於這個問題我們可以使用多值 map的方法解決:map[int][]string,用切片作為 map 的值
package main import "fmt" func main() { originMap := map[string]int{ "a":0, "b":0, "c":2, } fmt.Println(originMap) newMap := make(map[int][]string) for key,value := range originMap{ newMap[value] = append(newMap[value],key) } fmt.Println(newMap) }
輸出結果
map[b:0 c:2 a:0] map[0:[a b] 2:[c]]