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