# 字典的操作与约束

## 1. 约束

1. go中的字典其实是一个hash table的特定实现。所以键必须是可以哈希的（受限），值可以是任意类型的
2. Go的键不可以是函数类型、字典类型和切片类型。
   键类型的值必须要支持判等操作。
   但是这些类型不能进行判等，所以键类型不能是这些类型。？

## 2. 原理

1. 键值转为哈希值。

2. 哈希表持有一定数量的哈希桶，其中均匀存放键-值对。选择哪个桶，就是对哈希返回结果取模
   ```go
   index := hash("Key6") % array.len
   ```

   

3. 哈希表根据key的哈希值定位到哈希桶，查找其中键，因为键和值是绑定的，如果找到了键，就能返回其值
   *Go语言会把所有的哈希值存起来，传入key后，先取哈希值比较，如果都没有，那就直接返回，如有相等的，再比较键。*

4. 存在哈希冲突时，两种方法，拉链法与开放寻址法，一般用前者。参考2，有key肯定能找到值的。

## 3. 应用

1. 键转为哈希值，把要查找的键与哈希桶中的键做对比，比较耗时

2. 所以求哈希，判等的速度越快，就越适合作为键类型

3. key类型占用字节数越小，做哈希就越快

4. 数组、结构体、接口类型，不适合做哈希。

5. go的map 并发不安全。非原子操作需要枷锁，并发读写需要加锁，判断一个操作是否是原子的可以使用 go run race 命令做数据的竞争检测

   