proto 3 中的可选(重复)字段

Posted

技术标签:

【中文标题】proto 3 中的可选(重复)字段【英文标题】:Optional (repeated) field in proto 3 【发布时间】:2019-03-14 19:21:58 【问题描述】:

我使用 protobuf 和 proto 3 语法来定义消息。

我希望能够区分未提供值(未指定)的字段和设置/保留默认值的字段(0 用于 int32,[] 用于重复等)。 对于值,有众所周知的包装器允许这样做,但对于自定义消息,则由他自己来处理。

有些人提出了一种依赖 oneof 的技术,但它不适用于集合(重复或映射)。

现在我开始考虑系统地为每条消息编写包装器。

message MyMessage 
  int32 id = 1;
  string name = 2;
  // ...
  message Optional 
    MyMessage value = 1;
  
  message OptionalRepeated 
    repeated MyMessage values = 1;
      

即使MyMessage.OptionalRepeatedMyMessage.Optional 可能永远不会被使用。

我想人们一定已经开始依赖这种模式,所以也许已经有一个工具可以自动生成这个样板代码。 您知道减轻这种负担的工具吗?或者更好,有没有更好的方法?

【问题讨论】:

【参考方案1】:

在许多情况下,最好通过可选字段显式传达您试图隐式传达的含义。

通常它可以只是一个单独的bool 字段。例如:

message UpdateParameters

   bool updateServerList = 1;
   repeated ServerType serverList = 2;

这让阅读代码的人清楚,如果您想更新到[],您只需设置updateServerList = trueserverList = []。如果它是 optionalServerList 类型的单个字段,则不清楚如果参数丢失会发生什么,另一方面,如果没有额外的 cmets,空和丢失之间的区别可能会在任何实现另一侧的人身上丢失协议。

拥有一个单独的字段还为保持兼容性的更新提供了更多可能性。例如,您可以添加 Timestamp updateIfOlderThan = 3;,同时仍然保留为只知道 true/false 字段的旧客户端单独定义行为的可能性。

【讨论】:

【参考方案2】:

您可以使用google.protobuf.ListValue

https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/struct.proto

【讨论】:

以上是关于proto 3 中的可选(重复)字段的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中的可选参数[重复]

JavaScript中的可选链接[重复]

javascript中的可选参数[重复]

Python中的类/函数中的可选参数[重复]

Javascript:函数中的可选参数[重复]

烧瓶 add_url_rule 中的可选参数 [重复]