将protobuf结构体改为oneof后,新版本能否兼容读取旧版本生成的proto?
Protobuf Schema更新后的兼容性问题解答
结论
更新后的第二个版本多数场景下能读取第一个版本生成的proto,但存在特殊情况会导致数据异常。
具体场景分析
- 若旧版本
Foo消息仅设置了bar_1或bar_2其中一个字段:
新版本的oneof可以正常解析,对应字段的值会被正确读取,oneof的foo字段会指向被设置的那个值。 - 若旧版本
Foo消息同时设置了bar_1和bar_2两个字段:
新版本解析时只会保留最后被序列化的那个字段,另一个字段的值会直接丢失。因为oneof的语义是同一时间仅能有一个字段生效,而旧版本schema允许两个字段共存,这种情况下解析结果会和原始数据不一致。
兼容性原理
Protobuf的兼容性核心依赖字段编号和类型:
- 两个版本中
bar_1、bar_2的字段编号、类型均未改变,所以旧版本序列化的二进制数据本身可被新版本识别。 - 但新版本引入的oneof约束改变了消息语义规则——从允许双字段共存变为仅单字段生效,这才导致了双字段共存的旧数据解析时出现信息丢失。
内容的提问来源于stack exchange,提问作者A. Fenzry
相关产品推荐
相关产品推荐

