作者:程序员CKeen
博客:http://ckeen.cn
长期坚持做有价值的事!积累沉淀,持续成长,升维思考!希望把编码作为长期兴趣爱好
在 Go 语言中,map是一种基于哈希表实现的数据结构。哈希表是一种方便且功能强大的内置数据结构,它是一个无序的key/value键值对的集合。
哈希表一般写作map[K]V,其中K代表键,V代表K对应的值。哈希表通过给定的键Key可以在常数时间复杂度内检索、更新或删除对应的value,是一种比较常用的数据结构。
下面主要介绍一下map的具体的使用方法:
map1 := map[string]int {} // 先创建一个空map,不包含任何键值对
map1["foo"] = 1 // 添加一个键值对
map1["boo"] = 2
map1["hello"] = 3
fmt.Println(map1)
// map[boo:2 foo:1 hello:3] ,可以看到打印的结果是无序的
map2 := map[string]int { // 初始化创建一个包含键值对的map
"foo": 1,
"boo": 2,
"hello" : 3,
}
fmt.Println(map2)
// map[boo:2 foo:1 hello:3]
map3 := make(map[string]int)
map3["foo"] = 1
map3["boo"] = 2
map3["bar"] = 3
fmt.Println(map3)
// map[bar:3 boo:2 foo:1]
map4 := make(map[string]int)
map4["foo"] = 1
map4["boo"] = 2
map4["bar"] = 3
map4["bar"] = 4
fmt.Println(map4)
// map[bar:4 boo:2 foo:1]
创建一个map的集合对象后,只需要直接使用中括号添加key,然后=后面直接赋值即可。map4 := make(map[string]int)
map4["foo"] = 1
map4["boo"] = 2
map4["bar"] = 3
map4["bar"] = 4
barVal := map4["bar"]
fmt.Println(map4,barVal)
// map[bar:4 boo:2 foo:1] 4
hello := map4["hello"]
fmt.Println(hello)
// 打印 0
barVal2 := &map4["bar"] //Cannot take the address of 'map4["bar"]'
map中进行取值操作,如果key不存在的时候,它不会报错, 它会返回value的零值。而且map中的value值并不是一个变量,因此我们不能对map的元素进行取址操作map4 := make(map[string]int)
map4["foo"] = 1
map4["boo"] = 2
map4["bar"] = 3
delete(map4,"bar")
fmt.Println(map4)
直接使用go的库函数delete就可以完成删除key/value操作,当key不存在的时候,delete操作也不会报错,也没有任何反馈信息。因此如果你想知道是否你删除的键值对是否有删除, 可以先判断该键值对是否存在。map6 := make(map[string]int)
map6["foo"] = 1
map6["boo"] = 2
map6["bar"] = 3
map6["hello"] = 5
for k, val := range map6 {
fmt.Printf("key:%v,value:%v\n",k,val)
}
// key:foo,value:1
// key:boo,value:2
// key:bar,value:3
// key:hello,value:5
遍历map中全部的key/value对,使用range风格的for循环实现,和之前的slice遍历语法类似。map的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。实际遍历的顺序是随机的,每一次遍历的顺序都不相同。var keys []string
for key := range map4 {
keys = append(keys, key)
}
sort.Strings(keys)
for _, val := range map4 {
fmt.Printf("%s\t%d\n", val, ages[val])
}
map7 := map[string]int { // 初始化创建
"foo": 1,
"boo": 2,
"hello" : 3,
"test" : 0
}
fmt.Println(map7["test"],map7["world"])
// 打印的为零值 0 0
if val, ok := map7["world"]; ok {
fmt.Println(val)
}
// 不会打印结果
当前map的键不存在的时候,取到的值默认为零值。这样就存在当取到为零值的时候,无法判断到底是键不存在,还是存得键本身就为零值的情况,所以go利用多返回值的形式,可以来判断是否。同样如果我们结构内部对外的暴露的是一个map结构,如果不想外面的修改影响到内部的mpa结构,也可以将对外暴露的结构进行复制一个新的对外。