我正在尝试确定默认值与在各种编程接口中声明的 has_foo()方法之间的关系。特别是,我试图确定在什么情况下(如果有的话)你可以“明确地设置为默认值的字段与未设置值之间的差异”。
如果我明确地将字段(例如“Bar.foo”)设置为其默认值(例如,零),那么Bar :: has_foo()保证为该数据结构返回true吗? (对于C ++生成的代码,从快速检查来看似乎是这样,但这并不意味着它是有保证的。)如果这是真的,那么就可以区分显式设置的默认值和未设置的优先级序列化。
如果我明确地将字段设置为其默认值(例如,零),然后序列化该对象并通过网络发送,那么是否会发送该值?如果不是,那么显然任何接收此对象的代码都无法区分显式设置的默认值和未设置的值。即,在序列化之后将无法区分这两种情况 - 在两种情况下,Bar :: has_foo()都将返回false。
如果无法区分,如果我想编码一个“可空”的可选值,那么对protobuf字段进行编码的推荐技术是什么?我想到了几个选项,但看起来都不是很好:(a)添加一个额外的布尔字段来记录字段是否设置,或者(b)使用“重复”字段,即使我在语义上想要一个可选字段 - 通过这种方式,我可以区分无值(长度为零的列表)或设置值(长度为一的列表)。
答案 0 :(得分:27)
以下适用于'proto2'语法,而不适用于'proto3':
设置或不设置字段的概念是Protobuf的核心功能。如果将字段设置为值(任何值),则相应的has_xxx
方法必须返回true,否则API中存在错误。
如果未设置字段然后序列化消息,则不会为该字段发送任何值。接收方将解析消息,发现包含的值,并设置相应的“has_xxx”值。
具体如何以有线格式实现这一点:http://code.google.com/apis/protocolbuffers/docs/encoding.html。简短版本是该消息被编码为一系列键值对,并且只有明确设置的字段才包含在编码消息中。
当您尝试读取未设置的字段时,默认值才会起作用。