Go Map
#### Go map
***如果生命是一道墻,那么聲聲必有回響***
上一節(jié)我們學習了數(shù)組與切片,學習的還是基礎(chǔ)部分, 高級部分有二維數(shù)組,多維數(shù)組...;
在這里先不寫高級部分,高級部分與初級部分并沒有太大區(qū)別,一個是多維切片,在每一維使用前都需要make,第二個是遍歷時需要多層循環(huán);
##### map
在 Go 中map 是key:value 數(shù)據(jù)結(jié)構(gòu),類似python 中的字典;
基本語法:
var 變量名 map[keyType]valueType
其中key 可以是如下類型:
bool, 數(shù)字,string, 指針, channel,同樣還可以是包含前幾個類型的接口,結(jié)構(gòu)體,數(shù)組;
不過一般開發(fā)使用中key 通常為int,string;
key 需要滿足可以使用== 判斷,所以slice,map,函數(shù)這三個類型不可以作為map 的key ;
value 的數(shù)據(jù)類型同key 一樣, 通常為數(shù)字,string, map,struct;
案例: var a map[string]string var b map[int]string var c map[string]map[int]string var d map[string]int
map 是引用類型和slice 同樣,聲明或定義是不會分配內(nèi)存,初始化都需要make 才能使用; package mainimport "fmt"func main(){var a map[string]stringa = make(map[string]string)a["01"] = "01"a["02"] = "02"a["03"] = "03"a["01"] = "04"fmt.Println(a) }
1. map 在使用前需要make ;
2. map 的key 不能重復(fù),如果重復(fù)則key 的值為最后一次賦的值 ;
3. map 是無序的,所以如果需要對map 排序,則需要對key 進行排序 ;
---
##### map 的聲明和初始化方式 package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)a["01"] = "01"fmt.Println(a)// 2. 直接使用類型推導(dǎo)b := make(map[string]string)b["01"] = "01"fmt.Println(b)// 3. 字面量方式var c = map[string]string{"01":"01",}fmt.Println(c) }
##### map 的增刪改查
map 的增加和更改
map[key] = value // 如果map 內(nèi)不存在key 則屬于添加操作,否則屬于更改操作; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"// 更改操作a["01"] = "10"fmt.Println(a) // map[01:10 02:02] }
map 刪除
delete(map,key) ,delete 是內(nèi)置函數(shù),如果key 存在則會刪除這對key:value,如果key 不存在,則不會操作,也不會報錯; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"// 更改操作a["01"] = "10"fmt.Println(a) // map[01:10 02:02]// 刪除已經(jīng)存在的keydelete(a,"02")// 刪除不存在的key delete(a,"10") }
---
注意: 在Go 中沒有專門的函數(shù)可以一次性刪除map 中所以的key, 也就是說沒有辦法一次性清空map,
如果需要刪除所有的key, 則需要遍歷map , 一個一個刪除; 另一個辦法則是讓gc 回收: map = make(map[keyType][valueType]);
map 查找
val,res = map[key]
如果map 中存在key 則返回value,同時返回res=true,否則不會返回value,res=false; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"var value stringvar res boolvalue,res = a["01"]if res {// 如果有這個keyfmt.Println("key:01 value:",value)} else {// 如果沒有這個keyfmt.Println("no value",value)}value,res = a["10"]if res {// 如果有這個keyfmt.Println("key:10 value:",value)} else {// 如果沒有這個keyfmt.Println("no value",value)} }
##### map 的遍歷
map 的遍歷方式可以使用for-range 方式 package mainimport "fmt"func main() {// 1. 普通的mapvar a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"for key,value := range a {fmt.Println(key+"=",value)}// map 的value 還是一個mapvar b map[string]map[string]stringb = make(map[string]map[string]string)b["01"] = map[string]string{"001":"0001"} // 第二層這里使用的是字面量方式// 也可以使用這樣的方式c := make(map[string]string)c["002"] = "0002"b["02"] = cfmt.Println(b)// 復(fù)雜map 的遍歷for key,value := range b {for key2,value2 := range value {fmt.Printf("first key=%s,first value=%v | second key=%s,second value=%s\n",key,value,key2,value2)}} }
##### map 的長度使用len 函數(shù)
##### map 類型的切片
如果切片的數(shù)據(jù)類型是map , 那么map 的個數(shù)就可以動態(tài)變化了,這個在json 中比較常用,json 序列化和反序列化后面會學習到; package mainimport "fmt"func main() {// 聲明切片的類型為mapvar arr []map[string]string// 聲明一個map 類型var a map[string]string// 初始化mapa = make(map[string]string)// map 賦值a["01"] = "01"// 初始化切片arr = make([]map[string]string,0) // append 函數(shù)底層會檢查是否make ,所以這一行可以省略;arr = append(arr,a)// 再添加一個mapvar b map[string]stringb = make(map[string]string)b["001"] = "001"arr = append(arr,b)fmt.Println(arr) }
##### map 排序
在上面我們知道了,map 本身是無序的,所以排序需要先對key 排序,然后按排序后的key 輸出map即可; package mainimport ("fmt""sort" )func main() {var a map[string]stringa = make(map[string]string)a["01"] = "01"a["first"] = "first"a["second"] = "second"a["third"] = "third"a["fourth"] = "fourth"// 輸出是無序的,多運行幾次即可看到for k,v := range a {fmt.Println(k,v)}// 對map 排序,需要先對key 排序var keySlice []stringfor key,_ := range a {keySlice = append(keySlice,key)}// 排序// 排序前fmt.Println(keySlice)sort.Strings(keySlice)// 排序后fmt.Println(keySlice)// 按排序后的key 輸出mapfor _,key := range keySlice {fmt.Println(key,a[key])} }
map 的使用注意事項
1. map 是引用類型,遵守引用類型傳遞機制,在函數(shù)內(nèi)部修改后,會改變原來的值 ;
2. map 會自動擴容,可以動態(tài)增長; package mainimport "fmt"func test01(a map[string]string){// 新增加一個key:valuea["02"] = "02" } func main() {var a map[string]stringa = make(map[string]string)a["01"] = "01"a["first"] = "first"// 傳入函數(shù)前fmt.Println(a) //map[01:01 first:first]// 傳入函數(shù)后// 可以看出map 是引用類型,遵守引用傳遞機制test01(a)fmt.Println(a) //map[01:01 first:first 02:02] }
***如果生命是一道墻,那么聲聲必有回響***
上一節(jié)我們學習了數(shù)組與切片,學習的還是基礎(chǔ)部分, 高級部分有二維數(shù)組,多維數(shù)組...;
在這里先不寫高級部分,高級部分與初級部分并沒有太大區(qū)別,一個是多維切片,在每一維使用前都需要make,第二個是遍歷時需要多層循環(huán);
##### map
在 Go 中map 是key:value 數(shù)據(jù)結(jié)構(gòu),類似python 中的字典;
基本語法:
var 變量名 map[keyType]valueType
其中key 可以是如下類型:
bool, 數(shù)字,string, 指針, channel,同樣還可以是包含前幾個類型的接口,結(jié)構(gòu)體,數(shù)組;
不過一般開發(fā)使用中key 通常為int,string;
key 需要滿足可以使用== 判斷,所以slice,map,函數(shù)這三個類型不可以作為map 的key ;
value 的數(shù)據(jù)類型同key 一樣, 通常為數(shù)字,string, map,struct;
案例: var a map[string]string var b map[int]string var c map[string]map[int]string var d map[string]int
map 是引用類型和slice 同樣,聲明或定義是不會分配內(nèi)存,初始化都需要make 才能使用; package mainimport "fmt"func main(){var a map[string]stringa = make(map[string]string)a["01"] = "01"a["02"] = "02"a["03"] = "03"a["01"] = "04"fmt.Println(a) }
1. map 在使用前需要make ;
2. map 的key 不能重復(fù),如果重復(fù)則key 的值為最后一次賦的值 ;
3. map 是無序的,所以如果需要對map 排序,則需要對key 進行排序 ;
---
##### map 的聲明和初始化方式 package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)a["01"] = "01"fmt.Println(a)// 2. 直接使用類型推導(dǎo)b := make(map[string]string)b["01"] = "01"fmt.Println(b)// 3. 字面量方式var c = map[string]string{"01":"01",}fmt.Println(c) }
##### map 的增刪改查
map 的增加和更改
map[key] = value // 如果map 內(nèi)不存在key 則屬于添加操作,否則屬于更改操作; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"// 更改操作a["01"] = "10"fmt.Println(a) // map[01:10 02:02] }
map 刪除
delete(map,key) ,delete 是內(nèi)置函數(shù),如果key 存在則會刪除這對key:value,如果key 不存在,則不會操作,也不會報錯; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"// 更改操作a["01"] = "10"fmt.Println(a) // map[01:10 02:02]// 刪除已經(jīng)存在的keydelete(a,"02")// 刪除不存在的key delete(a,"10") }
---
注意: 在Go 中沒有專門的函數(shù)可以一次性刪除map 中所以的key, 也就是說沒有辦法一次性清空map,
如果需要刪除所有的key, 則需要遍歷map , 一個一個刪除; 另一個辦法則是讓gc 回收: map = make(map[keyType][valueType]);
map 查找
val,res = map[key]
如果map 中存在key 則返回value,同時返回res=true,否則不會返回value,res=false; package mainimport "fmt"func main(){// 1. 先聲明,再make ,最后使用var a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"var value stringvar res boolvalue,res = a["01"]if res {// 如果有這個keyfmt.Println("key:01 value:",value)} else {// 如果沒有這個keyfmt.Println("no value",value)}value,res = a["10"]if res {// 如果有這個keyfmt.Println("key:10 value:",value)} else {// 如果沒有這個keyfmt.Println("no value",value)} }
##### map 的遍歷
map 的遍歷方式可以使用for-range 方式 package mainimport "fmt"func main() {// 1. 普通的mapvar a map[string]stringa = make(map[string]string)// 增加操作a["01"] = "01"a["02"] = "02"for key,value := range a {fmt.Println(key+"=",value)}// map 的value 還是一個mapvar b map[string]map[string]stringb = make(map[string]map[string]string)b["01"] = map[string]string{"001":"0001"} // 第二層這里使用的是字面量方式// 也可以使用這樣的方式c := make(map[string]string)c["002"] = "0002"b["02"] = cfmt.Println(b)// 復(fù)雜map 的遍歷for key,value := range b {for key2,value2 := range value {fmt.Printf("first key=%s,first value=%v | second key=%s,second value=%s\n",key,value,key2,value2)}} }
##### map 的長度使用len 函數(shù)
##### map 類型的切片
如果切片的數(shù)據(jù)類型是map , 那么map 的個數(shù)就可以動態(tài)變化了,這個在json 中比較常用,json 序列化和反序列化后面會學習到; package mainimport "fmt"func main() {// 聲明切片的類型為mapvar arr []map[string]string// 聲明一個map 類型var a map[string]string// 初始化mapa = make(map[string]string)// map 賦值a["01"] = "01"// 初始化切片arr = make([]map[string]string,0) // append 函數(shù)底層會檢查是否make ,所以這一行可以省略;arr = append(arr,a)// 再添加一個mapvar b map[string]stringb = make(map[string]string)b["001"] = "001"arr = append(arr,b)fmt.Println(arr) }
##### map 排序
在上面我們知道了,map 本身是無序的,所以排序需要先對key 排序,然后按排序后的key 輸出map即可; package mainimport ("fmt""sort" )func main() {var a map[string]stringa = make(map[string]string)a["01"] = "01"a["first"] = "first"a["second"] = "second"a["third"] = "third"a["fourth"] = "fourth"// 輸出是無序的,多運行幾次即可看到for k,v := range a {fmt.Println(k,v)}// 對map 排序,需要先對key 排序var keySlice []stringfor key,_ := range a {keySlice = append(keySlice,key)}// 排序// 排序前fmt.Println(keySlice)sort.Strings(keySlice)// 排序后fmt.Println(keySlice)// 按排序后的key 輸出mapfor _,key := range keySlice {fmt.Println(key,a[key])} }
map 的使用注意事項
1. map 是引用類型,遵守引用類型傳遞機制,在函數(shù)內(nèi)部修改后,會改變原來的值 ;
2. map 會自動擴容,可以動態(tài)增長; package mainimport "fmt"func test01(a map[string]string){// 新增加一個key:valuea["02"] = "02" } func main() {var a map[string]stringa = make(map[string]string)a["01"] = "01"a["first"] = "first"// 傳入函數(shù)前fmt.Println(a) //map[01:01 first:first]// 傳入函數(shù)后// 可以看出map 是引用類型,遵守引用傳遞機制test01(a)fmt.Println(a) //map[01:01 first:first 02:02] }
最新文章會在微信公眾號,歡迎關(guān)注學習交流
轉(zhuǎn)載于:https://www.cnblogs.com/Mail-maomao/p/11458906.html
總結(jié)
- 上一篇: openresty开发系列39--ngi
- 下一篇: Go 面向对象之结构体