golang map

什么是map?

map是一个可以存储key/value对的一种数据结构,map像slice一样是引用类型,map内部实现是一个hash table,因此在map中存入的数据是无序的map内部实现)。而每次从map中读取的数据也是无序的,因为golang在设计之初,map迭代器的顺序就是随机的,有别于C/C++,虽然存入map的数据是无序的,但是每次从map中读取的数据是一样的(为什么每次读取顺序不一样)。

声明和初始化

  1. // 声明一个map,因为map是引用类型,所以m是nil
  2. var m map[KeyType]ValueType
  3. // 初始化方式一,空map,空并不是nil
  4. m := map[KeyType]ValueType{}
  5. //初始化方式二,两种初始化的方式是等价的
  6. m := make(map[KeyType]ValueType)

基本操作

  1. m := map[string]int{}
  2. // 增加一个key/value对
  3. m["Tony"] = 10
  4. // 删除Key Tony
  5. delete(m, "Tony")
  6. // 修改Key Tony的值
  7. m["Tony"] = 20
  8. // 判断某个Key是否存在
  9. if _, ok := m["Tony"]; ok {
  10. fmt.Println("Tony is exists")
  11. }
  12. // 遍历map
  13. for key, value := range m {
  14. fmt.Printf("Key = %s, Value = %d", key, value)
  15. }
  16. // 使用多个值对map进行初始化
  17. mp := map[string]int {
  18. "Tina": 10,
  19. "Divad": 20,
  20. "Tom": 5,
  21. }

Key和Value可以使用什么类型?

Key :只要是可比较(可以使用==进行比较,两边的操作数可以相互赋值)的类型就可以,像整形,字符串类型,浮点型,数组(必须类型相同);而map,slice和function不能作为Key的类型。

Value :任何类型都可以。

map中关于Key和Value类型参考

对map进行并发访问时需增加同步机制

map在并发访问中使用不安全,因为不清楚当同时对map进行读写的时候会发生什么,如果像通过goroutine进行并发访问,则需要一种同步机制来保证访问数据的安全性。一种方式是使用sync.RWMutex

  1. // 通过匿名结构体声明了一个变量counter,变量中包含了map和sync.RWMutex
  2. var counter = struct{
  3. sync.RWMutex
  4. m map[string]int
  5. }{m: make(map[string]int)}
  6. // 读取数据的时候使用读锁
  7. counter.RLock()
  8. n := counter.m["Tony"]
  9. counter.RUnlock()
  10. // 写数据的使用使用写锁
  11. counter.Lock()
  12. counter.m["Tony"]++
  13. counter.Unlock()

map并发访问参考