【问题标题】:How to design for a future additional enum value in protocol buffers?如何在协议缓冲区中设计未来的附加枚举值?
【发布时间】:2012-05-01 02:45:38
【问题描述】:

协议缓冲区的一个吸引人的特性是它允许您在不破坏使用旧定义的代码的情况下扩展消息定义。在枚举according to the documentation的情况下:

具有枚举类型的字段只能将一组指定的常量作为其值(如果您尝试提供不同的值,解析器会将其视为未知字段)

因此,如果您扩展枚举并使用新值,则旧代码中具有该类型的字段将未定义或具有其默认值(如果有)。

什么是处理这个问题的好策略,知道将来枚举可能会添加额外的值?

想到的一种方法是定义枚举的“未定义”成员并将其设为默认值,然后旧代码将知道它已发送无法解释的内容。这是否明智,有没有更好的方法来处理这种情况?

【问题讨论】:

  • 另一种解决方案是永远不要向现有枚举添加值,而是添加一个新枚举。
  • 从我今天一直盯着的代码(Java)来看,尚不清楚默认值是否有帮助。枚举字段已经有一个默认值(枚举的第一个值),但该值已分配并取消设置。因此,isInitialized() 失败,因为对所需字段的扫描发现 hasField 布尔值为 false。枚举,必需,可扩展 - 选择任意两个?
  • @VoiceOfUnreason:正确:如果您要求枚举,意外值将被视为不兼容。只有当它是可选的时,才有默认值。

标签: protocol-buffers


【解决方案1】:

是的,最好的方法是使枚举中的第一个值类似于UNKNOWN = 0。然后旧程序读取带有他们无法识别的枚举值的 protobuf 会将其视为UNKNOWN,并希望他们可以合理地处理它,例如通过跳过该元素。

如果您想这样做,您还需要将枚举设为 optional 而不是 required

required 通常意味着“我宁愿程序中止而不是处理它不理解的东西。”

请注意,它必须是 proto 源中声明的第一个值 - 只是零值并不能使其成为默认值。

【讨论】:

  • 我使用协议缓冲区版本 3 进行了测试,如果客户端尝试解组具有新值的枚举(客户端原型中尚未出现),它不会映射到第一个值(未知=0 在示例中),它只是抛出一个异常。这种行为导致我使用 String 而不是枚举,因为它会在客户端和服务器之间创建耦合。
【解决方案2】:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
  • 2011-09-18
  • 2021-12-19
  • 2011-11-15
  • 1970-01-01
相关资源
最近更新 更多