Proto3的设置值等于默认值,在运行时无法识别
Proto3
那样严格,并且没有required
或optional
字段,没有自定义的default
值。
鉴于以下定义…
message Order { enum Side { BID = 0; ASK = 1; } int64 time = 1; double price = 2; double volume = 3; Side side = 4; }
任何这些字段都有默认值,毕竟现在没有什么规则必须或不能在你的.build()
对象之前提供。
所以,默认的time
是0
, price
是0.0
, side
是BID
,如果你打印一个没有提供字段或者提供默认值的实例,那么运行时会把它当作从来没有提供过的,所以无法确定该值是手动设置为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作为一个选项(实际上你正在寻找的确切选项),而不是版本的变化。