go中无万能序列化方案,需按场景选格式:json适用于api但需注意字段导出、类型匹配;gob适合go内部通信但不跨语言;protobuf适合跨服务rpc;结构体应分层定义、避免标签混用,契约对齐是关键。

Go 里没有“万能序列化方案”,选错格式会导致字段丢失、性能下降、跨服务解析失败——关键不是怎么序列化,而是按场景选对格式和结构体定义方式。
json.Marshal/Unmarshal 用不对,字段就丢
JSON 是 API 交互首选,但 json.Marshal 默认只导出首字母大写的字段,小写字段或嵌套 interface{} 会直接被忽略;更隐蔽的是,nil slice 或 map 序列化成 null,但反序列化时若目标字段没设默认值,就会 panic。
- 结构体字段必须首字母大写,且加
json:标签明确映射(如`json:"user_id"`) - 避免在结构体里混用
map[string]interface{}和强类型字段——JSON 不保证字段顺序,且反序列化时类型推断不可靠 - 对可空字段,用指针类型(如
*string)而非零值类型,配合omitempty控制输出 - 遇到
json: cannot unmarshal string into Go struct field X.Y of type int,说明前端传了字符串,后端该字段却定义为int——要么改结构体加自定义UnmarshalJSON方法,要么让上游修正数据格式
gob 编码适合 Go 内部通信,但不能跨语言
encoding/gob 是 Go 自己的二进制序列化工具,性能比 JSON 高 3–5 倍,支持非导出字段、函数、channel 等运行时类型,但只在 Go 进程间有效。它不适合存 Redis(除非你确定所有读取方都是 Go),也不适合做 API 返回。
- 用
gob.NewEncoder+bytes.Buffer直接序列化结构体到字节流,比先转 JSON 再转 []byte 快得多 - 如果结构体含
interface{},gob 能完整保留类型信息;JSON 则会丢掉类型,变成map[string]interface{} - 注意:gob 文件或缓存内容不兼容 Go 版本升级——结构体字段增删、重命名都会导致
gob: unknown type错误,需配合gob.Register显式注册类型 - 存 Redis 时,gob 输出是二进制,必须再套一层
base64.StdEncoding.EncodeToString才能安全存储为字符串
protobuf 不是银弹,但适合微服务间高频通信
Protocol Buffers(protobuf)在跨语言、高性能 RPC 场景下优势明显,但引入了 .proto 文件、代码生成、版本兼容等额外复杂度。它不适合单机缓存或简单 HTTP API。
- 字段编号不能重复,新增字段必须用新编号,否则旧客户端解析失败
- Go 中用
proto.Marshal/proto.Unmarshal,不是json.Marshal——别混淆包路径:google.golang.org/protobuf/proto - 避免在 proto message 中定义过多嵌套或大数组,否则序列化时内存暴涨,触发
proto: message is too large - HTTP API 仍建议返回 JSON,用 protobuf 做服务间 gRPC 通信;二者共存时,不要强行把 proto struct 直接塞进
json.Marshal——字段标签冲突,且未导出字段无法序列化
结构体别打满标签,按用途拆开定义
一个结构体同时带 json:、bson:、xml:、gorm: 标签,等于把传输、存储、展示逻辑全耦合在一起。字段改一个,所有层都得测;加个新输出格式,就得改业务结构体。
- API 层用
api.UserResponse,只带json:标签;数据库层用db.UserModel,只带gorm:或bson: - 转换用显式赋值,而不是反射库——前者可 debug、可加日志、无运行时开销;后者黑盒、难排查、性能差
- 时间字段尤其敏感:数据库可能存 UTC,API 需要 ISO8601 字符串,前端又要求本地时区——用独立类型封装(如
HTime),在各层实现各自的MarshalJSON和Value方法 - 别为了“少写几行”而复用结构体,多几个文件换来的是清晰边界和长期可维护性
最常被忽略的点:序列化不是终点,而是数据契约的起点。字段名改一个,上下游是否同步更新?时间字段是否统一时区?nil slice 是该输出 [] 还是 null?这些问题不提前对齐,上线后就是线上事故。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











