4

Proto3没有那么严格Proto2,而且没有requiredoroptional字段,也没有自定义default值。

给定以下定义...

message Order {
    enum Side {
        BID = 0;
        ASK = 1;
    }

    int64 time = 1;
    double price = 2;
    double volume = 3;
    Side side = 4;
}

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

因此,timeis 0priceis0.0sideis的默认值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

至少这很烦人,因为当你使用标准.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生成不同的代码(影响默认行为)......

4

1 回答 1

4

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

于 2016-05-25T17:44:15.963 回答