前言
map是Golang内置的一个键值对容器,在开发中经常用到同时API简单易用,那么它和其他语言的关于map的实现有什么不同吗?下面就来学习一下~
简单使用
初始化
1 | // 声明一个map,为引用类型的零值nil |
CRUD
1 | m := map[string]int{} |
需要注意Key需要是可比较类型,即能够使用==操作符进行比对的类型,像map
、slice
、function
等都是不行的。 同时map类型也是线程不安全的,如果有多线程同时进行操作的话,可以使用RWMutex
或者sync.map来保证线程安全。
原理
Golang主要使用bmap
和hmap
两个结构体来实现map类型,同时不像Java只使用链表/红黑树来解决hash冲突,而是主要使用数组来解决。
hmap结构
1 | // A header for a Go map. |
bmap主要结构
字段 | 解释 |
---|---|
topbits | 类型为[]uint8,存放key获取的hash的高8位,遍历时对比使用,为了提高性能 |
key | 具体key的数组 |
elems | 具体value得数组 |
overflow | 指向的hmap.extra.overflow 溢出桶里的bmap ,上面的字段topbits 、keys 、elems 长度为8,最多存8组键值对,存满了就往指向的这个bmap 里存 |
主要逻辑大致如图
当bmap里存放满8位键值对,便会尝试使用overflow扩展[]bmap,来处理hash冲突的问题,当overflow对应的[]bmap也满的时候便会进行扩容。