Go-12-序列化与 struct tag 深入
本节目标:掌握 JSON / gob / msgpack / protobuf / YAML 等序列化方案,深入 struct tag 高级用法。
1. encoding/json 完整用法
1.1 基本类型
1 | type User struct { |
1.2 struct tag 选项
1 | type Config struct { |
| 选项 | 作用 |
|---|---|
omitempty |
零值省略 |
string |
数字/布尔序列化为字符串 |
- |
完全忽略该字段 |
,inline |
嵌入字段展开(Go 1.19+) |
1.3 嵌入 struct
1 | type Base struct { |
改名嵌入:
1 | type User struct { |
用 omitempty 避免 ID=0 也输出:
1 | type User struct { |
1.4 自定义序列化
1 | // 实现 json.Marshaler 接口 |
1.5 延迟解析(RawMessage)
有时 JSON 中某个字段结构不确定,先存起来后续解析:
1 | type Event struct { |
1.6 流式处理
1 | // 大数组流式写 |
2. encoding/gob(Go 二进制)
gob 是 Go 专用的二进制序列化,比 JSON 快、紧凑,但只支持 Go 之间。
1 | import "encoding/gob" |
优势:支持任意 Go 类型(函数、chan 除外),自动处理结构体演化。
劣势:跨语言不通(Java/Python 读不了)。
3. msgpack(推荐跨语言高性能场景)
需要 github.com/vmihailenco/msgpack/v5:
1 | import "github.com/vmihailenco/msgpack/v5" |
msgpack 优势:
- 比 JSON 小、快
- 支持二进制、整数、浮点、字符串、数组、map
- 跨语言(Python、Java、JS 都有库)
- 适合 RPC、高性能存储
4. protobuf(gRPC 标配)
最适合微服务/跨语言 RPC:
1 | // user.proto |
1 | # 编译生成 Go 代码 |
1 | import "google.golang.org/protobuf/proto" |
优势:
- 强类型、字段编号稳定(演化友好)
- 高性能(比 JSON 快 5-10x,比 msgpack 也快)
- 跨语言(gRPC 标准)
5. YAML
需要 gopkg.in/yaml.v3:
1 | import "gopkg.in/yaml.v3" |
常用 YAML 库:
gopkg.in/yaml.v3:纯 Go 实现,主流选择gopkg.in/yaml.v2:老版本
6. struct tag 高级技巧
6.1 多种序列化器共存
1 | type User struct { |
6.2 自定义 tag 解析
1 | // reflect 解析自定义 tag |
6.3 实现 validator(用 go-playground/validator)
1 | import "github.com/go-playground/validator/v10" |
常用验证 tag:
required:必填min=N, max=N:长度/数值范围email、url、uuid、ipv4等oneof=red green blue:枚举regexp=^pattern$:正则
7. 实战:HTTP API 统一响应格式
1 | type Response struct { |
8. 实战:自定义 JSON 字段顺序
Go 的 json.Marshal 按字段声明顺序输出,可以巧妙控制:
1 | type User struct { |
如果用 map[string]interface{} 字段顺序就乱了。
9. 性能对比
| 格式 | 体积 | 速度 | 跨语言 | 可读性 |
|---|---|---|---|---|
| JSON | 大 | 慢 | ✅ | ✅ |
| gob | 中 | 快 | ❌ | ❌ |
| msgpack | 小 | 快 | ✅ | ❌ |
| protobuf | 最小 | 最快 | ✅ | ❌ |
| YAML | 很大 | 最慢 | ✅ | ✅ |
选择建议:
- 配置 / 文档:YAML
- HTTP API / 调试:JSON
- Go 内部 RPC / 缓存:gob
- 跨语言高性能 / 微服务:protobuf / msgpack
10. 性能优化技巧
1. 用 jsoniter 或 easyjson 替换标准库:
1 | go get github.com/json-iterator/go |
1 | import jsoniter "github.com/json-iterator/go" |
2. 避免反射:用 easyjson 生成 Marshal/Unmarshal 代码
1 | go get github.com/mailru/easyjson |
3. 流式处理大文件:
1 | dec := json.NewDecoder(f) |
小结
| 场景 | 推荐格式 |
|---|---|
| 配置文件 | YAML |
| HTTP REST API | JSON |
| Go 内部通信 | gob / protobuf |
| 跨语言 RPC | protobuf (gRPC) |
| 高性能缓存 | msgpack / gob |
| 前端友好 | JSON |
struct tag 是 Go 序列化的灵魂:
- 业务字段映射(
json:"name") - 验证规则(
validate:"required") - 数据库列名(
db:"column_name") - 文档生成(
example:"...")
下一节深入并发控制:sync.Mutex、context、连接池。
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/08/21/Go-12-序列化与struct-tag深入/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!