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()函数分配到内存空间,这样才能在其中存放键值对。
func testVar() {
var map1 map[string]string
fmt.Printf("%T,%v,len()=%d,nil?%v", map1, map1, len(map1), map1 == nil)
//map[string]string,map[],len()=0,nil?true
}
使用make函数声明map
格式:变量名 := make(map[key类型]value类型)
该声明方式,如果不初始化map,那么map也不等于nil
func testMake() {
map2 := make(map[string]string)
fmt.Printf("%T,%v,len()=%d,nil?%v", map2, map2, len(map2), map2 == nil)
//map[string]string,map[],len()=0,nil?false
}
声明Map后直接赋值。
func testMap1() {
//如果是多行,最后一个也必须加上,号
var m1 = map[string]string{
"HuBei": "WuHan",
"HuNan": "ChangSha",
"JiangSu": "NanJing",
"ZheJiang": "NingBo",
}
//如果是单行,则不需要在最后加上“,”号,但加上“,”号也是可以的
m2 := map[string]string{"HuBei": "WuHan", "HuNan": "ChangSha", "JiangSu": "NanJing", "ZheJiang": "NingBo"}
fmt.Printf("%T,%v,len()=%d,nil?%v \n", m1, m1, len(m1), m1 == nil)
fmt.Printf("%T,%v,len()=%d,nil?%v \n", m2, m2, len(m2), m2 == nil)
}
声明Map后,再给map赋值。
func testMap2() {
m1 := make(map[string]string)
m1["HuBei"] = "WuHan"
m1["HuNan"] = "ChangSha"
m1["JiangSu"] = "NanJing"
m1["ZheJiang"] = "NingBo"
fmt.Printf("%T,%v,len()=%d,nil?%v \n", m1, m1, len(m1), m1 == nil)
}
遍历map。
var m0 = map[string]string{"HuBei": "WuHan", "HuNan": "ChangSha", "JiangSu": "NanJing", "ZheJiang": "NingBo"}
//遍历key和value
func testRangeMap1() {
for k,v := range m0{
fmt.Println("省:",k,",省会:",v)
}
}
遍历map中的value
func testRangeMap2() {
for _,v := range m0{
fmt.Println("省会:",v)
}
}
遍历map中的key
func testRangeMap3() {
for k := range m0{
fmt.Println("省:",k)
}
}
查看元素在集合中是否存在
我们可以通过key获取map中对应的value值,语法为:map[key]
当key如果不存在的时候,会得到该value值类型的默认值,比如string类型得到空字符串,int类型得到0,但是程序不会报错。
所以可以通过value,ok := map[key],获取key/value是否存在,ok是bool型,如果是true,则该键值对存在。
func findMapKey1() {
val1,ok1 := m0["HuBei"]
fmt.Println(val1,ok1)
val2,ok2 := m0["HeiLongJiang"]
fmt.Println(val2,ok2)
}
func findMapKey2(str string,m map[string]string) {
val,ok := m[str]
if ok {
fmt.Println("查询到",str,"省的省会为:",val)
} else {
fmt.Println("未能检索到该数据")
}
}
//findMapKey2的简化版本
func findMapKey3(str string,m map[string]string) {
if val,ok := m[str];ok {
fmt.Println("查询到",str,"省的省会为:",val)
} else {
fmt.Println("未能检索到该数据")
}
}
delete(map,key)函数用于删除集合的某个元素,参数为map和其对应的key。
删除函数不返回任何值。
func deleteMap1() {
fmt.Printf("删除以前:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
if _,ok := m0["HuNan"];ok{
delete(m0,"HuNan")
}
fmt.Printf("删除以后:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
}
Go语言没有为map提供清空集合所有元素的函数;
清空map唯一的方法是新建一个map,然后赋给目标map;
func deleteMap2() {
fmt.Printf("清空以前:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
m0 = map[string]string{}
fmt.Printf("清空以后:%T,%v,len()=%d,nil?%v \n", m0, m0, len(m0), m0 == nil)
}