
在 go 中,声明但未初始化的 map 是 nil 值,对其直接赋值会触发 panic:“assignment to entry in nil map”;正确做法是使用 make() 创建一个可写的空 map。
在 go 中,声明但未初始化的 map 是 nil 值,对其直接赋值会触发 panic:“assignment to entry in nil map”;正确做法是使用 make() 创建一个可写的空 map。
Go 的 map 是引用类型,但与其他语言不同——声明一个 map 变量(如 var m map[K]V)并不会自动分配底层数据结构,而是得到一个 nil map。nil map 行为受限:可安全地进行读操作(返回零值),但任何写操作(包括 m[key] = value 或 delete(m, key))都会立即 panic。
在你的代码中:
var countedData map[string][]ChartElement // ← 此时 countedData == nil
for el := range out {
countedData[el.Name] = el.Data // ⚠️ panic:assignment to entry in nil map
}countedData 未初始化,循环首次尝试写入即崩溃,因此 fmt.Println 永远不会执行。
✅ 正确做法:使用 make() 显式初始化 map:
func receiveWork(out <-chan Work) map[string][]ChartElement {
countedData := make(map[string][]ChartElement) // ✅ 分配底层哈希表
for el := range out {
countedData[el.Name] = el.Data
}
fmt.Println("This is now executed ✅")
return countedData
}? 进阶建议(提升健壮性):
- 若预期键数量较稳定,可预设容量以减少扩容开销:
countedData := make(map[string][]ChartElement, 16) - 若需追加元素(而非整体替换),注意 []ChartElement 是切片,可配合 append 使用:
countedData[el.Name] = append(countedData[el.Name], el.Data)
- 在并发场景中(如多个 goroutine 向同一 map 写入),需额外加锁(sync.RWMutex)或改用 sync.Map——但本例中 receiveWork 是单 goroutine 消费 channel,无需同步。
总结:Go 中 map 必须 make() 后才能写入;这是初学者高频踩坑点,牢记“声明 ≠ 初始化”,养成 := make(...) 的初始化习惯,即可彻底避免该 panic。


















