Go 语言 JSON 处理:结构体标签与 Marshal 原理

2025-01-30

Go 没有动态对象字面量,JSON 靠 struct + tag 映射。写 API 时 tag 打错、零值 omitempty 误用,是联调里最高频的「JSON 对不上」来源。

结构体 tag 基础

`json:"field_name,omitempty"` 控制键名与空值省略;`-` 忽略字段。

未导出字段(小写)不会被 encoding/json 处理。

type User struct {
  ID   int    `json:"id"`
  Name string `json:"name,omitempty"`
}

Unmarshal 与类型

数字默认 float64 进 interface{};精确大整数用 json.Number 或 struct。

未知字段默认忽略;DisallowUnknownFields 可严格模式。

json.RawMessage

延迟解析:外层 struct 先 Unmarshal,内层 JSON 留 RawMessage 稍后再解析。

适合多态 payload 或「先校验再分支」的流程。

Marshal 原理简述

反射遍历字段,按 tag 取名;不支持 channel、func。

性能敏感路径可用 jsoniter、sonic 等库,但标准库在多数 API 场景足够。