
`json.unmarshal` 函数返回的是错误(error)类型,`nil` 表示解析成功;开发者误将其当作解码结果打印,导致误解为“未解码”。实际解码后的值通过传入的指针参数(如 `&p`)获取。
在 Go 语言中,json.Unmarshal 的函数签名如下:
func Unmarshal(data []byte, v interface{}) error它不返回解码后的值,而是将解析结果写入第二个参数 v 所指向的变量中,并仅返回一个 error 类型的值:
- 若解析成功 → 返回 nil;
- 若解析失败(如 JSON 格式错误、字段类型不匹配、结构体字段未导出等)→ 返回具体错误。
你遇到的输出:
Unmarshalled:
正是因为 uncoded := json.Unmarshal(coded, &p) 将 error 赋值给了 uncoded,而该 error 为 nil(即解析成功),所以打印出来是
✅ 正确写法应分离错误处理与结果使用:
coded := redis.LoadFromBase()
err := json.Unmarshal(coded, &p)
if err != nil {
log.Fatalf("JSON unmarshal failed: %v", err)
}
fmt.Println("Bytes:", coded)
fmt.Println("Unmarshalled:", p) // ← 此处打印的是解码后的结构体/变量 p,不是 err? 关键注意事项:
- p 必须是可寻址的变量(因此需传 &p);
- 若 p 是结构体,其字段必须以大写字母开头(导出字段),否则 json 包无法设置值;
- 建议始终检查 err,即使日志显示 nil,也不代表数据语义正确(例如空字节切片或 null 值可能静默成功);
- 可配合 json.Valid() 预检 JSON 合法性,提升调试效率:
if !json.Valid(coded) {
log.Fatal("Invalid JSON bytes")
}? 小技巧:使用 fmt.Printf("%+v") 打印结构体,可清晰查看各字段值及标签映射是否符合预期。
总之,json.Unmarshal 返回 nil 是成功的标志,不是异常信号——理解 Go 的错误处理范式(显式返回 error、不抛异常)是避免此类困惑的核心。










