外观
map
Phase 01 — Go Fundamentals · 知识点 09
1. 学习目标
- 创建和使用 map
- 理解 key 必须可比较(comparable)
- 掌握取值、赋值、删除、遍历
- 理解 nil map 与 make 的区别
2. 为什么需要
需要按 ID 快速查找设备:"AGV-001" → 状态对象。map 提供 O(1) 均摊查找,是后端缓存、索引、配置表的基础结构。
3. 核心概念
go
// 声明与初始化
status := make(map[string]string)
status["AGV-001"] = "moving"
// 字面量
battery := map[string]int{
"AGV-001": 85,
"AGV-002": 42,
}
// 取值
v, ok := status["AGV-001"] // ok 表示 key 是否存在
delete(status, "AGV-001")| 要点 | 说明 |
|---|---|
| key 类型 | string、int 等可比较类型;slice/map/function 不能作 key |
| 零值 | nil map,不能赋值,需 make |
| 并发 | 非线程安全,并发需 sync.Map 或加锁 |
| 遍历顺序 | 随机,不保证顺序 |
4. 基础语法
go
package main
import "fmt"
func main() {
devices := make(map[string]float64)
devices["AGV-001"] = 1.2
devices["AGV-002"] = 0.8
for id, speed := range devices {
fmt.Printf("%s: %.1f m/s\n", id, speed)
}
if speed, ok := devices["AGV-003"]; ok {
fmt.Println(speed)
} else {
fmt.Println("device not found")
}
}5. 代码解析
v, ok := m[key]是 idiomatic 的存在性检查- 不存在的 key 取值返回零值,
ok == false delete(m, key)删除,key 不存在也不报错
6. JavaScript / TypeScript 对比
| Go map | JS |
|---|---|
map[string]int 强类型 | Record<string, number> / Object |
| 非线程安全 | 单线程无此问题 |
| 遍历顺序随机 | Object 键顺序有规则,Map 按插入 |
7. 常见错误
- 对 nil map 赋值 → panic,先 make
- 在 range 中 delete → 合法但需谨慎
- 期望有序遍历 → map 无序,需 sort keys
- 并发读写 map → panic,需 Mutex
8. 实际应用
go
// 设备最新位置索引
positions := map[string]Position{
"AGV-001": {X: 10, Y: 5},
"AGV-002": {X: 30, Y: 15},
}
// 在线设备计数
onlineCount := map[string]bool{}WebSocket 连接管理:map[string]*Connection 按设备 ID 索引连接。
9. 深入理解
map 底层是哈希表。负载因子过高会扩容。大数据量时考虑预分配:make(map[string]int, 100)。
10. 练习
- L1:创建 map,增删查遍历
- L2:
v, ok模式处理不存在 key - L3:map 值为 struct
- L4:设备状态 map 模拟
11. 学习检查
- [ ] nil map 能赋值吗?
- [ ] 如何判断 key 存在?
- [ ] map 能并发读写吗?
12. 下一步
→ struct:将多个字段组合成设备对象