gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 07:50:49 45 4
gpt4 key购买 nike

我正在尝试升级到使用 protobuf 版本 3,并保持与版本 2 向后兼容。除了一件事之外似乎可以工作 - 在 proto-2 中您可以设置自己的默认值,但在 proto 3 中,您不能。如果您在 proto-2 中选择的默认值不是 proto-3 中的标准默认值,那么您就有问题了。例如,在 proto-2 中:

message Record {
required uint32 fileno = 1;
required uint64 pos = 2;
optional uint64 bmsPos = 3 [default = 0];
optional uint32 scanMode = 4 [default = 9999];
}
现在在 proto-3 中必须是:
message Record {
uint32 fileno = 1;
uint64 pos = 2;
uint64 bmsPos = 3;
uint32 scanMode = 4;
}
在 proto-2 和 proto-3 中,都不会在消息中发送缺失值。但是 proto-3 API 不会告诉您默认值是否在消息中,它只是告诉您该值。
因此 proto-3 接收器收到一条消息并告诉我 scanMode = 0 .如果该消息来自 proto-2 发送者,则 1) proto-2 发送者在消息中放置 0,或 2) proto-2 发送者将该值设置为 9999(默认值),因此该值未发送,proto-3 接收器将其解释为 0。在不知道消息中是否存在该值的情况下,我的代码无法消除歧义,即使它知道消息是来自 proto-2 还是来自proto-3 发件人。
请注意, bmsPos 没有问题示例中的字段,因为 proto-2 消息使用与 proto-3 (0) 相同的默认值。但是,如果您碰巧选择了与 proto-3 不同的默认值,那么我不知道如何升级到 proto-3 并向后兼容。

最佳答案

原来有一种方法可以确定默认值是否确实缺失(感谢谷歌的一些 friend 提供了这个答案):

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() 方法:
int scanMode = proto.getScanMode();
boolean isMissing = proto.getScanModePresentCase() == Record.ScanModePresentCase.SCANMODEPRESENT_NOT_SET;
if (isMissing) {
boolean isProto3 = proto.getVersion() >= 3;
scanMode = (isProto3) ? 0 : 9999;
}
  • 请注意,oneof 的名称是任意的,我采用了约定 fieldname_present。
  • oneof 不会向有线格式添加任何内容,因此它与 proto-2 消息保持兼容。
  • 你可以在任何有意义的地方添加版本信息,我把它放在这个例子的记录消息中。

  • 通过这个“技巧”,我已经升级到 proto-3,向后兼容非标准的 proto-2 默认值。

    关于protocol-buffers - 将 protobuf 从版本 2 升级到 3 - 与 protobuf 默认值不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33204321/

    45 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com