在golang中,map是散列表的引用,也就是说它是引用类型,像指针那样。
map的类型是map[K]V
,所有元素的key都K类型,所有元素的value都是V类型。
m := make(map[string]int) // 方式一
m := map[string]int{} // 方式二
避免对零值(未初始化)的map设置kv。
var ages map[string]int
ages["tom"] = 12 // 异常
var ages := map[string]int{}
ages["tom"] = 12 // 正常
赋值
m["foo"] = 1
m["bar"] = 2
// 初始化带赋值
m2 := map[string]int{
"foo": 1,
"bar": 2, //注意这个标点符号,是不能少的Ï
}
通过key来访问元素,通过内置的delete
函数,根据key来删除元素
m["hello"] = 3
fmt.Println(m["hello"]) // 3
delete(m, "hello")
fmt.Println(m["hello"]) // 0
fmt.Println(m["nothing"]) // 0
访问不存在的key,也不会抛出异常,而是会返回map value的零值。
fmt.Println(m["nothing"]) // 0
m["nothing"]++
fmt.Println(m["nothing"]) // 1
既然不管key存在不存在,map都会返回一个值,那如何区分map里到底是包含了个本来就是空值的key还是根本没有这个key呢?
其实通过key来访问value的话,返回两个值,第一个值是元素的value,第二个值就是这个key是否存在。
if value, ok := m["nothing-2"]; ok {
fmt.Println("存在,value = " + strconv.Itoa(value))
} else {
fmt.Println("不存在")
}
map的元素不是一个变量,所以无法获取它的地址, &m["foo"]
无法通过编译,其中一个原因是随着map的增长,它会重新散列已有元素,这样的话原地址就无法保证了。
for k, v := range m {
fmt.Printf("%s = %d\n", k, v)
}
map是无序的,如果向按照key的字典顺序来遍历,则需要借助数组和sort
包
names := make([]string, 0, len(m))
for k := range m {
names = append(names, k)
}
sort.Strings(names)
for _, name := range names {
fmt.Printf("%s = %d\n", name, m[name])
}
和slice一样,map不可比较。
使用一个map[T]bool
类型的map来充当set,往"set"里增加元素时,m[key]=true
,然后通过判断m[key]
是否true来判断"set"中是否存在key。
map中的key必须是可比较的,并且不建议使用float和double。如果你想用double、slice等作为key的话,可以参考java的做法,自己实现一个确定的hashCode()
方法,编码出来一个string或int。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://laozhu.blog.csdn.net/article/details/121237785
内容来源于网络,如有侵权,请联系作者删除!