首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将protobuf从版本2升级到3--与protobuf默认值不兼容

将protobuf从版本2升级到3--与protobuf默认值不兼容
EN

Stack Overflow用户
提问于 2015-10-18 23:17:12
回答 1查看 31.3K关注 0票数 44

我试图升级到使用Proto3版本,并与版本2保持向后兼容。除了一件事--在proto-2中,您可以设置自己的默认值,但在proto 3中,您不能。如果您选择了proto-2中的默认值,而这不是proto-3中的标准默认值,那么您就有问题了。例如,在原语2中:

代码语言:javascript
运行
复制
message Record {
  required uint32 fileno = 1;               
  required uint64 pos = 2;                  
  optional uint64 bmsPos = 3 [default = 0]; 
  optional uint32 scanMode = 4 [default = 9999];  
}

现在第三原语必须是:

代码语言:javascript
运行
复制
message Record {
  uint32 fileno = 1;               
  uint64 pos = 2;                  
  uint64 bmsPos = 3; 
  uint32 scanMode = 4;  
}

在proto-2和proto-3中,没有在消息中发送缺少的值。但是Proto-3API并不告诉您默认值是否在消息中,它只是告诉您这个值。

所以proto-3接收器收到一条消息,并告诉我scanMode = 0.如果该消息来自原-2发送方,则原语-2发送方在消息中放置0,或者2)原-2发送方将值设置为9999 (默认值),因此不发送该值,而proto-3接收方将其解释为0。在不知道消息中是否存在值的情况下,我的代码无法消除歧义,即使它知道消息是来自proto-2还是proto-3发送方。

请注意,示例中的bmsPos字段没有问题,因为proto-2消息使用与proto-3 (0)相同的默认值。但是,如果您碰巧选择了一个与proto-3不同的默认值,那么我就不知道如何升级到proto-3并向后兼容。

EN

回答 1

Stack Overflow用户

发布于 2015-10-18 23:40:42

事实证明,有一种方法可以找出默认值是否真的丢失(感谢google的一些朋友提供了这个答案):

代码语言:javascript
运行
复制
message Record {
  uint32 fileno = 1;               
  uint64 pos = 2;                  
  uint64 bmsPos = 3; 
  oneof scanMode_present {
    uint32 scanMode = 4;
  }
  uint32 version = 5; // set to >= 3 for protobuf 3 
}

使用getXXXcase()方法,生成代码有其他方法来检测是否设置了一个字段:

代码语言:javascript
运行
复制
int scanMode = proto.getScanMode();
boolean isMissing = proto.getScanModePresentCase() == Record.ScanModePresentCase.SCANMODEPRESENT_NOT_SET;
if (isMissing) {
  boolean isProto3 = proto.getVersion() >= 3;
  scanMode = (isProto3) ? 0 : 9999;
}
  • 请注意,其中一个名称是任意的,我已经采用了约定fieldname_present。
  • 其中一个不添加任何东西到有线格式,所以它保持与原-2消息兼容。
  • 您可以在任何有意义的地方添加版本信息,我将其放在本例的记录消息中。

有了这个“技巧”,我已经升级到原-3与非标准的原-2默认值向后兼容。

票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33204321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档