go-内置数据结构的实现原理
管道
切片
每个切片都指向一个底层数组
数据结构
1 | // src/runtime/slice.go:slice |
操作
使用数组创建slice
使用数组创建slice时,slice将与原数组共用一部分内存。
扩容
扩容的本质:重新分配内存(len > cap时),拷贝数据,追加数据。
- cap < 1024, cap = 2 * cap
- cap > 1024, cap = 1.25 cap
Map
Go语言的map基于Hash表实现。
特性
初始化
1 | // make初始化 |
增删改查
1 | func MapCRUD() { |
删除元素使用内置函数delete完成
数据结构
- map的数据结构
一个Hash表中可以有多个bucket,每个bucket保存了map中的一个或多个键值对
1 | // runtime/map.go:hmap |
- bucket的数据结构
1 | // runtime/map.go:bmap |
每个bucket可以存储8个键值对
- tophash是一个长度为8的整型数组,Hash值低位相同的键存入当前bucket时会将Hash值的高位存储在该数组中,以便后续匹配。
扩容
触发条件
- 负载因子大于6.5
- overflow > 2^15
过程
- oldbuckets指向原buckets数组
- 申请新buckets = 2 * buckets
- 更新buckets指针
- 迁移数组
- 释放oldbuckets
增删改查
查找
根据key计算hash值
hash低位 % hmap.B
取hash值高位,在tophash数组中查询
若tophash[i] == key.hash,则获取tophash[i]的key值进行比较
当前bucket中没有找到,则依次从溢出的bucket中查找
Struct
字段标签
Tag的本质
String
特点:string使用8比特字节的集合来存储字符,存储的是字符的UTF-8编码。在使用for-range遍历时,index可能不连续
1 | func StringIteration() { |
类型转换
string转[]byte
1 | func StringToByte() { |
[]byte转string
1 | func ByteToString() { |
数据结构
1 | // src/runtime/string.go:stringStruct |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Napleon!
评论