简介
映射是一种数据结构,用于存储一系列无序的键值对,能够基于键快速检索数据
内部实现(待完善)
映射的实现使用了散列表,因此每次迭代映射的时候顺序可能不一样
- 散列表中需要关注的两个数据结构
hmap
bucket
注意:
在字节数组中,键值是存放在一起的,目的是为了节省空间,多个键可以存储在同一个内存单元中,消除带来的空间浪费
两者的关系
Go语言哈希函数会将键进行哈希运算,得到唯一的值,并将求得的值分为高位和低位,其中低位用于寻找该键属于hmap
中的哪一个bucket
,高位用于寻找该bucket
中哪一个key
- 加载因子
每种哈希表的都会有一个加载因子,数值超过加载因子就会为哈希表扩容
当插入的元素个数与桶个数的商达到6.5
时,会产生一个新的buckets
数组,将旧数组赋值到oldbucket
中,只有当访问到具体的某个bucket的时候,才会把bucket中的数据转移到新的bucket中
这里并不会直接删除旧的bucket,而是把原来的引用去掉,利用垃圾回收机制清除内存
另外:
在映射中删除数据时,如果键或值是指针类型,则会被置为空,等待垃圾回收机制清楚内存,如果是值类型,则被清理相关内存,最后将该键的高位置对应数组索引置空
图文参考RyuGou
创建和初始化
- Make
dict:=make(map[string]int)
dict2:=make(map[string]string){"Red":"da1337","Orange":"#e95a22"}
- 使用映射字面量声明空映射
映射的键可以是任何值,只要这个值可以用==
运算符做比较,切片、函数以及包含切片的结构类型具有引用语义,不能作为映射的键,否则会编译出错
dict:=map[int][]string{}
使用映射
- 为映射赋值
colors:=map[string]string{}
colors["Red"]="#da1337"
可以通过声明一个未初始化的映射来创建一个值为nil的映射,nil映射不能用于存储键值对,否则会报错
var colors map[string]string
colors["Red"]="#da1337"
Runtime Error
- 从映射获取值并判断键是否存在
value,exists:=colors["Blue"]
if exists{
fmt.Println(value)
}
- 使用
range
迭代映射
for key,value:=range colors{
...
}
返回的是键值对
- 从映射中删除一项
delete(colors,"Coral")
在函数间传递映射
在函数间传递映射并不会制造出该映射的一个副本,跟传递切片类似,对这个映射做了修改时,所有对这个映射的引用都会察觉到这个修改