为什么在原型3中没有自定义默认值?

原型2版本的协议缓冲允许为消息元素指定默认值:

optional double scaling_factor = 3 [default = 1.0];

为什么这在 原型3中不再可能?我认为这是一个简洁的特性,可以节省电线上的额外字节,而不需要编写任何包装代码。

43217 次浏览

我的理解是,Proto3不再允许您检测字段存在,也不再支持非零默认值,因为这使得在不同语言中以“普通的旧结构”的形式实现 Protobufs 变得更加容易,而不需要生成访问器方法。这被认为使 Protobuf 在这些语言中更容易使用。

(我个人认为缺少访问器和属性的语言不是很好的语言,原型程序不应该设计成这样,但这不再是我的项目了。)

在我的自动生成文件. pb.cc 中,我看到了几个类似的地方:

if (this->myint() != 0) {

很少有这样的:

myint_ = 0;

因此,为什么不启用默认值并生成

static ::google::protobuf::int32 myint_defaultvalue = 5;


...
if (this->myint() != myint_defaultvalue) {
...


...
myint_ = myint_defaultvalue;
...

取而代之?

这是一个解决方案,而不是直接回答你的问题,但我发现自己使用 wrappers.proto 可选值,然后自己设置默认值时,我绝对必须知道这是一个默认值或显式设置的值。

代码必须强制执行值而不是生成的代码本身并不是最佳选择,但是如果您同时拥有两边,至少它是一个可行的替代方案,而不是不知道该值是默认值还是显式设置,特别是当看到一个 bool 设置为 false 时。

我不清楚这对线路上的字节有什么影响。对于我使用它的实例,消息长度不是一个设计约束。

原始文件

import "google/protobuf/wrappers.proto";


google.protobuf.BoolValue optional_bool = 1;

Java 代码

//load or receive message here
if( !message.hasOptionalBool() )
message.setOptionalBool( BoolValue.newBuilder().setValue( true ) );