//读取(key 不存在返回 value 类型的零值) age := ages["bob"] // 0
//判断 key 是否存在(逗号 ok 惯用法) age, ok := ages["bob"] if !ok { /* bob 不存在 */ }
//常见简写:读取并判断 if age, ok := ages["bob"]; ok { // bob 存在,使用 age }
//删除(key 不存在也不会 panic,安全操作) delete(ages, "alice")
//遍历(⚠️ 顺序随机,每次运行不同) for name, age := range ages { fmt.Printf("%s\t%d\n", name, age) }
//长度 len(ages)
4. nil map vs 空 map
1 2 3 4 5
var m map[string]int// nil map(未初始化) // 方式一:make(已初始化,非 nil) m = make(map[string]int) // 方式二:字面量(已初始化,非 nil) m = map[string]int{}
操作
nil map
空 map
读取
✅ 安全,返回零值
✅ 安全
len()
✅ 返回 0
✅ 返回 0
delete()
✅ 安全
✅ 安全
写入
❌ panic
✅ 正常
重要:向 nil map 写入会 panic,使用前必须先 make 或用字面量初始化。
5. 重要限制
❌ 不能对 map 元素取地址
1
_ = &ages["alice"] // ❌ 编译错误
💡 原因:map 增长时可能重新分配内存,元素地址会失效。
❌ 不能用 == 比较两个 map
1 2 3
a := map[string]int{"x": 1} b := map[string]int{"x": 1} // a == b ❌ 编译错误(只能与 nil 比较)
需要手动实现比较逻辑:
1 2 3 4 5 6 7 8 9
funcequal(x, y map[string]int)bool { iflen(x) != len(y) { returnfalse } for k, xv := range x { if yv, ok := y[k]; !ok || yv != xv { returnfalse } } returntrue }
6. 有序遍历
map 遍历顺序是随机的,需要排序时:
1 2 3 4 5 6 7 8 9 10 11 12 13
// 1. 提取所有 key names := make([]string, 0, len(ages)) for name := range ages { names = append(names, name) }
// 2. 对 key 排序 sort.Strings(names)
// 3. 按排序后的 key 遍历 for _, name := range names { fmt.Printf("%s\t%d\n", name, ages[name]) }
7. 实用技巧
🔹 用 map 实现 Set
Go 没有内置 Set 类型,用 map[string]bool 或 map[string]struct{} 代替:
1 2 3 4 5
seen := make(map[string]bool) if !seen[item] { seen[item] = true // 处理 item... }