Protocol buffers 如何在协议缓冲区中为将来的附加枚举值进行设计?

Protocol buffers 如何在协议缓冲区中为将来的附加枚举值进行设计?,protocol-buffers,Protocol Buffers,协议缓冲区的一个吸引人的特性是,它允许您扩展消息定义,而不破坏使用旧定义的代码。对于枚举,请执行以下操作: 枚举类型的字段只能有一组指定的常量中的一个作为其值(如果尝试提供不同的值,解析器会将其视为未知字段) 因此,如果扩展枚举并使用新值,则旧代码中具有该类型的字段将未定义或具有其默认值(如果有) 如果知道将来enum可能会添加其他值,那么处理这个问题的好策略是什么 想到的一种方法是定义枚举的一个“未定义”成员,并将其设为默认值,然后旧代码将知道它已发送了无法解释的内容。这是否合理,是否有更好的

协议缓冲区的一个吸引人的特性是,它允许您扩展消息定义,而不破坏使用旧定义的代码。对于枚举,请执行以下操作:

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

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

如果知道将来enum可能会添加其他值,那么处理这个问题的好策略是什么


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

是的,最好的方法是将枚举中的第一个值设置为类似于
UNKNOWN=0
。然后,旧的程序读取带有他们不识别的枚举值的protobuf时,会将其视为
未知
,希望它们能够合理地处理它,例如跳过该元素

如果要执行此操作,还需要将枚举设置为
可选
必需

required
,通常意味着“我宁愿程序中止,也不愿处理它不理解的事情。”


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

进一步的解决方案是永远不要向现有枚举添加值,而是添加一个新的枚举。从我今天开始的代码(Java)来看,不清楚默认值是否有帮助。枚举字段已具有默认值(枚举的第一个值),但该值已分配并取消设置。因此,isInitialized()失败,因为对所需字段的扫描发现hasField布尔值为false。枚举,必需,可扩展-选择任意两个?@VoiceOfUnreason:Correct:如果将枚举设为必需,则意外值将被视为不兼容。只有在可选的情况下,使用默认值才有帮助。我使用协议缓冲区版本3进行了测试,如果客户机试图解组具有新值(在客户机协议中尚未出现)的枚举,它不会映射到第一个值(示例中为UNKNOWN=0),它只会抛出异常。这种行为导致我使用字符串而不是枚举,因为它会在客户机和服务器之间创建耦合。