首页 > 解决方案 > proto 3 中的可选(重复)字段

问题描述

我使用 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可能永远不会使用。

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

标签: protocol-buffers

解决方案


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

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

message UpdateParameters
{
   bool updateServerList = 1;
   repeated ServerType serverList = 2;
}

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

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


推荐阅读