
go语言中声明但未初始化的map是nil值,直接赋值会触发“assignment to entry in nil map” panic;必须通过make()或字面量语法显式初始化后才能使用。
go语言中声明但未初始化的map是nil值,直接赋值会触发“assignment to entry in nil map” panic;必须通过make()或字面量语法显式初始化后才能使用。
在Go中,map 是引用类型,但与其他语言(如Python的dict或ruby的Hash)不同:仅声明不等于初始化。如下语句:
var m map[String]int
只是声明了一个类型为 map[string]int 的变量 m,其值为 nil —— 此时 m 尚未分配底层哈希表结构,任何写操作(如 m[key] = value)都会立即引发运行时 panic:
panic: assignment to entry in nil map
这正是你代码中 m[c_string[i]] = 0 报错的根本原因。
✅ 正确做法是显式初始化map。推荐两种等效方式:
立即学习“go语言免费学习笔记(深入)”;
方式一:使用 make() 函数(最常用、语义清晰)
m := make(map[string]int) // 初始化空map,可安全读写
方式二:使用 map 字面量(简洁,适合初始化带默认值的场景)
m := map[string]int{} // 等价于 make(map[string]int) // 或带初始键值对: m := map[string]int{"a": 1, "b": 2}
⚠️ 注意:var m map[string]int 后若需复用该变量,必须单独调用 m = make(map[string]int) —— 不能跳过初始化步骤。
此外,你的去重逻辑存在逻辑缺陷:当前实现中 if m[c_string[i]]
func removeDuplicate(s string) string { m := make(map[string]bool) // 更语义化:只需记录是否存在 var result []string // 使用切片累积结果,避免字符串重复拼接 for _, char := range strings.Split(s, "") { if !m[char] { m[char] = true result = append(result, char) } } return strings.Join(result, "") }
? 关键总结:
- Go中所有map必须初始化(make() 或字面量)后才能写入;
- nil map 可安全读取(返回零值),但写入必panic;
- 遍历字符串建议用 for _, r := range s 处理Unicode更健壮,但本例中按字节切分亦可满足ASCII场景;
- 字符串拼接优先使用 []string + strings.Join(),避免 += 导致的多次内存分配。
掌握这一基础机制,能有效规避大量Go新手踩坑,也是理解Go内存模型与类型安全的重要一课。