Go学习笔记1.3 map剖析

map类型

是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。

使用方法

  1. 基本语法

声明是不会分配内存的,初始化分配内存后才能赋值和使用。

    声明 
        var map t map[int]int
    初始化
        t = make(map[int]int,0)
        var t map[int]int = map[int]int{1,1}
        t = map[int]int{1}
    读取
        i := m["a"] 
        i,ok := m["b"] //可用第二个参数判断是否存在
    删除
        delete(m,"a")
  1. key类型
key类型可以是 bool、数字、string、指针、channel , 只包含前面几个类型的接口、结构体、数组,通常为 int 或 string 但是 slice map func 不可以
  1. value类型
value类型基本和key一样 通常为数字 字符串 接口
  1. 常用案例
map[string]string
map[int]string
map[int]interface

常见问题

  1. 赋值问题
map 在 go 中属于 reference 类型 作为传参或返回类型的时候 传递的也是地址 不是map本体 map 在没有初始化的时候为 nil
  1. append对未初始化的map
append 支持 非nil和nil的map,都能进行成功的append
  1. map线程安全
map 是非线程安全的 可以通过内嵌的结构体加 读写锁 实现线程安全

声明
    var counter = struct{
        sync.RWMutex
        m map[string]int
    }{m: make(map[string]int)}
读
    counter.RLock()
    n := counter.m["some_key"]
    counter.RUnlock()
    fmt.Println("some_key:", n)
写
    counter.Lock()
    counter.m["some_key"]++
    counter.Unlock()
  1. 读取顺序问题
map 是 hashmap 读取遍历是无法保证顺序的 如果保证key的遍历顺序可以通过将key保存到一个slice
    
    import "sort"

    var m map[int]string
    var keys []int
    for k := range m {
        keys = append(keys, k)
    }
    sort.Ints(keys)
    for _, k := range keys {
        fmt.Println("Key:", k, "Value:", m[k])
    }
  1. map 扩容和缩容
    map 无法打印 kay value 的值 会随着map的扩容改变
    但是 map 删除key 无法自动缩容 
    

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。