gob仅限Go进程间安全使用,因其是Go专属二进制格式,不带字段名、无跨语言兼容性、不保证版本兼容,未导出字段被忽略,且必须显式注册类型并配对使用Encoder/Decoder。

gob 不适合跨语言或长期存储,只推荐在 Go 进程间(如 RPC、本地缓存)安全使用。
为什么不能用 gob 做 JSON 那种通用序列化
gob 是 Go 专属二进制格式,不带字段名、不兼容版本变更、不保证向后/向前兼容。比如 struct 加个字段,旧版程序读取会直接 panic;换成其他语言根本无法解析。
- 错误现象:
gob: unknown type id 123或decoding into interface{} of unregistered type - 本质原因:gob 依赖运行时注册的类型 ID,且默认只 encode/exported 字段(首字母大写)
- 适用场景:同一套 Go 代码的 client/server 通信、内存 → 文件临时快照(如单元测试 fixture)、goroutine 间通道传复杂结构
必须显式注册自定义类型才能 encode/decode
Go 的 gob 包不会自动发现 struct 类型,未注册就 encode 会 panic;decode 时若类型未注册或不匹配,会报 gob: type not registered for interface。
- 注册方式:调用
gob.Register(),参数是类型本身(不是实例),例如gob.Register(MyStruct{})或gob.Register(&MyStruct{}) - 如果 struct 含指针、interface{}、map[string]interface{} 等,其底层具体类型也得注册(比如
map[string]*User中的*User) - 建议在
init()函数里统一注册,避免漏掉;RPC 场景下 client/server 必须注册完全一致的类型集
encode 和 decode 必须用成对的 encoder/decoder
不能混用 gob.NewEncoder(w) 和 gob.NewDecoder(r) 的底层 reader/writer,尤其不能把同一个 bytes.Buffer 拿来反复 encode/decode 而不清空。
- 典型错误:先
enc.Encode(v1),再enc.Encode(v2),但 decode 时只调一次dec.Decode(&v)—— 结果只拿到 v1,v2 还在 buffer 里“等着” - 正确做法:每个 encode/decode 操作应配对使用独立的
Encoder/Decoder,或确保bytes.Buffer在 encode 前.Reset(),decode 前.Bytes()可靠截取完整数据 - 注意:gob 不是流式协议,多次
Encode()产生的数据是拼接的,Decode()每次只消费一个完整值,不会自动跳过残留字节
struct 字段必须导出且类型可编码
未导出字段(小写开头)会被 gob 完全忽略,即使你设了值也不会出现在序列化结果中;同时,字段类型必须是内置类型、已注册类型、或能递归分解为这些类型的组合。
- 常见不可编码类型:
func、chan、unsafe.Pointer、未注册的自定义 struct 指针 - 切片和 map 默认可编码,但元素类型仍需满足可编码条件(比如
[]*UnregisteredType会失败) - 示例:这个 struct 的
private字段永远不会被 encode
type User struct {
Name string
Age int
private string // ← gob 直接跳过
}
真正麻烦的是类型注册遗漏和 buffer 复用——这两个点线上出问题时很难 debug,因为错误不总在 encode 侧爆发,而是在下游 decode 时静默失败或 panic。


















