写点什么

Go 学习笔记之 Map

发布于: 45 分钟前
Go 学习笔记之 Map

哈希表是一种巧妙并且实用的数据结构。它是一个无序的 key/value 对的集合,其中所有的 key 都是不同的,然后通过给定的 key 可以在常数时间复杂度内检索、更新或删除对应的 value。

在 Go 语言中,一个 map 就是一个哈希表的引用,map 类型可以写为 map[K]V,其中 K 和 V 分别对应 key 和 value。map 中所有的 key 都有相同的类型,所有的 value 也有着相同的类型,但是 key 和 value 之间可以是不同的数据类型。

创造 map

内置的 make 函数可以创建一个 map:

ages := make(map[string]int) // mapping from strings to ints
复制代码

我们也可以用 map 字面值的语法创建 map,同时还可以指定一些最初的 key/value:

ages := map[string]int{    "alice":   31,    "charlie": 34,}
复制代码

另一种创建空的 map 的表达式是:map[string]int{}

访问

Map 中的元素通过 key 对应的下标语法访问:

ages["alice"] = 32fmt.Println(ages["alice"]) // "32"
复制代码

使用 delete 函数可以删除元素:

delete(ages, "alice") // remove element ages["alice"]
复制代码

这些操作是安全的,即使这些元素不在 map 中也没有关系。


取址

map 中的元素并不是一个变量,因此我们不能对 map 的元素进行取址操作:

_ = &ages["bob"] // compile error: cannot take address of map element
复制代码

禁止对 map 元素取址的原因是 map 可能随着元素数量的增长而重新分配更大的内存空间,从而可能导致之前的地址无效。

遍历

遍历 map 中全部的 key/value 对的话,可以使用 range 风格的 for 循环实现,和之前的 slice 遍历语法类似。下面的迭代语句将在每次迭代时设置 name 和 age 变量,它们对应下一个键/值对:

for name, age := range ages {    fmt.Printf("%s\t%d\n", name, age)}
复制代码

Map 的迭代顺序是不确定的,并且不同的哈希函数实现可能导致不同的遍历顺序。在实践中,遍历的顺序是随机的,每一次遍历的顺序都不相同。

零值

map 类型的零值是 nil,也就是没有引用任何哈希表。

var ages map[string]intfmt.Println(ages == nil)    // "true"fmt.Println(len(ages) == 0) // "true"
复制代码

map 上的大部分操作,包括查找、删除、len 和 range 循环都可以安全工作在 nil 值的 map 上,它们的行为和一个空的 map 类似。但是向一个 nil 值的 map 存入元素将导致一个 panic 异常:

ages["carol"] = 21 // panic: assignment to entry in nil map
复制代码

在向 map 存数据前必须先创建 map。


Go 语言中并没有提供一个 set 类型,但是 map 中的 key 也是不相同的,可以用 map 实现类似 set 的功能。



作者:架构精进之路,十年研发风雨路,大厂架构师,CSDN 博客专家,专注架构技术沉淀学习及分享,职业与认知升级,坚持分享接地气儿的干货文章,期待与你一起成长

关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。



Thanks for reading!

发布于: 45 分钟前阅读数: 2
用户头像

坚持分享接地气儿的架构技术文章! 2018.02.26 加入

同名微信公众号「架构精进之路」,专注软件架构研究,技术学习与职业成长!坚持原创总结、沉淀和分享,希望能带给大家一些引导和启发,感谢各位的支持(关注、点赞、分享)!

评论

发布
暂无评论
Go 学习笔记之 Map