Go学习笔记1.3 map剖析
map类型
是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。
使用方法
- 基本语法
声明是不会分配内存的,初始化分配内存后才能赋值和使用。
声明
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")
- key类型
key类型可以是 bool、数字、string、指针、channel , 只包含前面几个类型的接口、结构体、数组,通常为 int 或 string 但是 slice map func 不可以
- value类型
value类型基本和key一样 通常为数字 字符串 接口
- 常用案例
map[string]string
map[int]string
map[int]interface
常见问题
- 赋值问题
map 在 go 中属于 reference 类型 作为传参或返回类型的时候 传递的也是地址 不是map本体 map 在没有初始化的时候为 nil
- append对未初始化的map
append 支持 非nil和nil的map,都能进行成功的append
- 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()
- 读取顺序问题
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])
}
- map 扩容和缩容
map 无法打印 kay value 的值 会随着map的扩容改变 但是 map 删除key 无法自动缩容
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。