Go语言Map详解
2024年1月1日
本文详细介绍Go语言map的底层实现原理和使用方法。
1. Map概念基础
Go语言中的map是一种哈希表实现,用于存储键值对数据。Go中map底层采用哈希表,用变种拉链法来解决哈希冲突问题。
1.1 哈希冲突
哈希冲突是指不同的键计算出相同的哈希值:

1.2 解决哈希冲突的方法
拉链法
拉链法通过链表结构来解决哈希冲突:

开放地址法
开放地址法通过探测空闲位置来解决哈希冲突:

2. Map底层数据结构
2.1 整体结构
- map是一个指向hmap的指针,该指针占用8个字节
- hmap是一个结构体,包含多个bucket数组(但并不是只有bucket)
- bucket数组的元素为bmap结构体,通过链表结构把bmap结构体连接起来
- 一个bmap结构体能存放8个键值对,而不是一个

2.2 hmap结构体
hmap是map的主要数据结构:

字段含义:

2.3 mapextra结构体
mapextra包含了一些额外的字段:

字段含义:

2.4 bmap结构体
hmap真正存储数据的是buckets指向的bmap(桶)数组:

字段含义:

3. Map工作原理
3.1 tophash机制
- map会根据每一个key算出一个hash值
- hash值是一分为二使用的,分成:高位、低位

tophash就存放高8位。
在上面的map底层结构图可以看到,bmap显示存储了8个tophash值,然后存储了8个键值对。
注意:
- 这8个键值对不是按照key + value这样key和value一起存储的。而是先存完连续的8个key,再存连续的8个value
- 当键值对不够8个时,对应位置留空,这样子存储的好处是可以消除字节对齐带来的空间浪费
3.2 Map访问原理
Map提供两种访问方式:

访问步骤:

3.3 Map赋值原理
Map赋值操作:

赋值流程:

