map是Go语言中的内置类型,它将一个值与一个键关联起来,可以使用相应的检索。
有翻译成地图、映射或字典(python),更多的翻译为集合(java)
map是一种无序的键值对(key-value pair)的集合,map通过key来快速检索数据,key类似于索引,指向乡音的value值。
map是一种集合,可以向遍历数组和切片一样去遍历它,不过map是无序的,所以无法决定它展示的顺序,这是因为map是使用的hash表来实现的。
map是无序的,每次打印出来的map都会不一样,它不能通过index获取,必须通过key获取;
map的长度是不固定的,和slice切片一样可以扩展,内置的len()函数同样适用于map,返回map拥有的键值对的数量,但是map不能通过cap()函数计算容量,或者说cap()函数的参数不能是map。
同一个map中key必须保证唯一性,key的数据类型必须是可参与比较运算的类型,也就是支持==或者!=操作的类型,比如布尔、整数、浮点、字符串、数组。对于切片、函数、map等引用类型则不行。
map的value可以是任何数据类型。
和slice一样,map也是一种引用类型。

Map 初始化

使用var map关键字声明map

格式:var 变量名 map[key类型]value类型
var声明变量,默认map是nil,nil map不能用来存放键值对。
var声明后,要么声明时初始化,要么再使用make()函数分配到内存空间,这样才能在其中存放键值对。

  1. func testVar() {
  2. var map1 map[string]string
  3. fmt.Printf("%T,%v,len()=%d,nil?%v", map1, map1, len(map1), map1 == nil)
  4. //map[string]string,map[],len()=0,nil?true
  5. }

使用make函数声明map

格式:变量名 := make(map[key类型]value类型)
该声明方式,如果不初始化map,那么map也不等于nil

  1. func testMake() {
  2. map2 := make(map[string]string)
  3. fmt.Printf("%T,%v,len()=%d,nil?%v", map2, map2, len(map2), map2 == nil)
  4. //map[string]string,map[],len()=0,nil?false
  5. }

声明Map后直接赋值。

  1. func testMap1() {
  2. //如果是多行,最后一个也必须加上,号
  3. var m1 = map[string]string{
  4. "HuBei": "WuHan",
  5. "HuNan": "ChangSha",
  6. "JiangSu": "NanJing",
  7. "ZheJiang": "NingBo",
  8. }
  9. //如果是单行,则不需要在最后加上“,”号,但加上“,”号也是可以的
  10. m2 := map[string]string{"HuBei": "WuHan", "HuNan": "ChangSha", "JiangSu": "NanJing", "ZheJiang": "NingBo"}
  11. fmt.Printf("%T,%v,len()=%d,nil?%v \n", m1, m1, len(m1), m1 == nil)
  12. fmt.Printf("%T,%v,len()=%d,nil?%v \n", m2, m2, len(m2), m2 == nil)
  13. }

声明Map后,再给map赋值。

  1. func testMap2() {
  2. m1 := make(map[string]string)
  3. m1["HuBei"] = "WuHan"
  4. m1["HuNan"] = "ChangSha"
  5. m1["JiangSu"] = "NanJing"
  6. m1["ZheJiang"] = "NingBo"
  7. fmt.Printf("%T,%v,len()=%d,nil?%v \n", m1, m1, len(m1), m1 == nil)
  8. }

遍历map。

  1. var m0 = map[string]string{"HuBei": "WuHan", "HuNan": "ChangSha", "JiangSu": "NanJing", "ZheJiang": "NingBo"}
  2. //遍历key和value
  3. func testRangeMap1() {
  4. for k,v := range m0{
  5. fmt.Println("省:",k,",省会:",v)
  6. }
  7. }

遍历map中的value

  1. func testRangeMap2() {
  2. for _,v := range m0{
  3. fmt.Println("省会:",v)
  4. }
  5. }

遍历map中的key

  1. func testRangeMap3() {
  2. for k := range m0{
  3. fmt.Println("省:",k)
  4. }
  5. }

查看元素在集合中是否存在

我们可以通过key获取map中对应的value值,语法为:map[key]
当key如果不存在的时候,会得到该value值类型的默认值,比如string类型得到空字符串,int类型得到0,但是程序不会报错。
所以可以通过value,ok := map[key],获取key/value是否存在,ok是bool型,如果是true,则该键值对存在。

  1. func findMapKey1() {
  2. val1,ok1 := m0["HuBei"]
  3. fmt.Println(val1,ok1)
  4. val2,ok2 := m0["HeiLongJiang"]
  5. fmt.Println(val2,ok2)
  6. }
  7. func findMapKey2(str string,m map[string]string) {
  8. val,ok := m[str]
  9. if ok {
  10. fmt.Println("查询到",str,"省的省会为:",val)
  11. } else {
  12. fmt.Println("未能检索到该数据")
  13. }
  14. }
  15. //findMapKey2的简化版本
  16. func findMapKey3(str string,m map[string]string) {
  17. if val,ok := m[str];ok {
  18. fmt.Println("查询到",str,"省的省会为:",val)
  19. } else {
  20. fmt.Println("未能检索到该数据")
  21. }
  22. }

delete(map,key)函数用于删除集合的某个元素,参数为map和其对应的key。

删除函数不返回任何值。

  1. func deleteMap1() {
  2. fmt.Printf("删除以前:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
  3. if _,ok := m0["HuNan"];ok{
  4. delete(m0,"HuNan")
  5. }
  6. fmt.Printf("删除以后:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
  7. }

Go语言没有为map提供清空集合所有元素的函数;

清空map唯一的方法是新建一个map,然后赋给目标map;

  1. func deleteMap2() {
  2. fmt.Printf("清空以前:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
  3. m0 = map[string]string{}
  4. fmt.Printf("清空以后:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
  5. }