第 7 章 / 共 20 章
映射 map
声明、增删查、遍历、并发安全
声明与初始化
package main
import "fmt"
func main() {
m := map[string]int{
"alice": 30,
"bob": 25,
}
// 用 make
m2 := make(map[string]int)
m2["x"] = 1
fmt.Println(m, m2)
}读 / 写 / 删除
package main
import "fmt"
func main() {
m := map[string]int{"alice": 30, "bob": 25}
m["alice"] = 31 // 写
v := m["alice"] // 读
fmt.Println(v)
if cv, ok := m["carol"]; ok { // 判断是否存在
fmt.Println("carol:", cv)
} else {
fmt.Println("carol missing")
}
delete(m, "bob") // 删
fmt.Println(m)
}遍历
range 遍历 map 的顺序是随机的,需要顺序请先把 key 排序。
package main
import (
"fmt"
"sort"
)
func main() {
m := map[string]int{"bob": 1, "alice": 2, "carol": 3}
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, m[k])
}
}并发安全
map 不是并发安全的。多 goroutine 读写需要加锁,或使用 sync.Map(适合读多写少、key 集合相对稳定的场景)。
package main
import (
"fmt"
"sync"
)
func main() {
var (
mu sync.Mutex
m = map[string]int{}
)
set := func(k string, v int) {
mu.Lock()
defer mu.Unlock()
m[k] = v
}
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
set(fmt.Sprintf("k%d", i), i)
}(i)
}
wg.Wait()
fmt.Println(len(m))
}