外观
常见问题
约 494 字大约 2 分钟
2025-06-19
本文记录 Go 开发中常见问题的排查与解决方案。
no such host 域名解析失败
golang net 包解析域名时提示 no such host,通常是 DNS 解析问题。
临时方案:关闭 cgo,使用纯 Go DNS 解析器
CGO_ENABLED=0 go build长期方案:
- 检查 DNS 配置(Linux:
/etc/resolv.conf) - 使用公网 DNS:
8.8.8.8或114.114.114.114 - 设置环境变量:
GODEBUG=netdns=cgo
slice 重复元素导致数据污染
使用 make([]T, len, cap) 时注意容量分配:
// 错误:共享底层数组
rows := make([]Row, 0, n)
for i := 0; i < n; i++ {
row := Row{}
rows = append(rows, row)
}
// 正确:每次创建新实例
for i := 0; i < n; i++ {
rows = append(rows, Row{})
}map 并发读写 panic
map 不是并发安全的,多个 goroutine 同时读写会 panic。
// 方案:使用 sync.RWMutex
mu := sync.RWMutex{}
data := make(map[string]string)
// 读
mu.RLock()
v := data["key"]
mu.RUnlock()
// 写
mu.Lock()
data["key"] = "value"
mu.Unlock()Go 1.9+ 也可使用 sync.Map,适合读多写少的场景。
defer 在循环中的陷阱
// 错误:资源可能无法及时释放
for _, path := range paths {
f, _ := os.Open(path)
defer f.Close() // 所有 defer 在循环结束后才执行
}
// 正确:在循环内使用闭包
for _, path := range paths {
func() {
f, _ := os.Open(path)
defer f.Close()
// 使用 f
}()
}nil pointer vs zero value
var s *string // nil
fmt.Println(*s) // panic: nil pointer dereference
var s string // ""
fmt.Println(s) // 正常输出空字符串使用指针类型时要确保不为 nil,或在访问前做判空检查。
json: cannot unmarshal object into Go struct
反序列化失败时,检查:
- struct 字段是否导出(首字母大写)
- json tag 是否与 JSON 键名一致
- 目标字段类型是否匹配
中文乱码
json.Marshal 对含中文的字符串会转义为 Unicode。
// 关闭转义
enc := json.NewEncoder(w)
enc.SetEscapeHTML(false)
// 或使用 Marshal 后手动替换(不推荐)