Proto3的设置值等于默认值,在运行时无法识别

Proto3那样严格,并且没有requiredoptional字段,没有自定义的default值。

鉴于以下定义…

 message Order { enum Side { BID = 0; ASK = 1; } int64 time = 1; double price = 2; double volume = 3; Side side = 4; } 

任何这些字段都有默认值,毕竟现在没有什么规则必须或不能在你的.build()对象之前提供。

所以,默认的time0price0.0sideBID ,如果你打印一个没有提供字段或者提供默认值的实例,那么运行时会把它当作从来没有提供过的,所以无法确定该值是手动设置为BID还是作为默认值。

例如,如果我们执行下面的代码(它的kotlin)

 Order.newBuilder() .setPrice(1.0) .setVolume(2.0) .setSide(Order.Side.BID) .build() .apply { println(this) } 

我们会有这个输出

 price: 1.0 volume: 2.0 

至少这是恼人的,当你打印你的proto对象使用标准的.toString()或JSON打印机,你将有这个裁剪输出…

 { "price": 1.0, "volume": 2.0 } { "price": 1.0, "volume": 2.0, "side": "ASK" } { "price": 1.0, "volume": 2.0 } { "price": 1.0, "volume": 2.0, "side": "ASK" } 

但是,如果你的客户不一定关心默认值,并希望所有的字段都存在,那该怎么办呢?

问题:有没有办法改变这种行为? 至少我们如何确保如果价值确定的话,它正在显示?

也许有一种方法告诉protoc生成不同的代码(影响默认行为)…

如果你想Proto2的默认值和设置/取消设置行为,你应该切换回Proto2。 Proto2不可能很快就会消失,因为很多代码(包括Google的内部代码)仍然依赖于它,并且它与Proto3共享大部分代码。 把proto2和proto3作为一个选项(实际上你正在寻找的确切选项),而不是版本的变化。