为什么proto3中没有自定义默认值?

Dan*_*uli 39 protocol-buffers proto3

协议缓冲区的proto2版本允许指定消息元素的默认值:

optional double scaling_factor = 3 [default = 1.0];
Run Code Online (Sandbox Code Playgroud)

为什么proto3中不再可能这样?我认为这是一个简洁的功能,可以在线上保存额外的字节,而无需编写任何包装代码.

Ken*_*rda 52

我的理解是proto3不再允许你检测字段存在而不再支持非零默认值,因为这样可以更容易地用各种语言的"普通旧结构"实现protobufs,而无需生成存取方法.这被认为使Protobuf更容易在这些语言中使用.

(我个人认为缺乏访问器和属性的语言不是很好的语言,protobuf不应该设计它们,但它不再是我的项目了.)

  • @MeirionHughes - 我相信问题出现在实例化一个新对象时,而不是脱线.如果您的语言不提供构造函数的概念而没有提供访问器的概念,那么您无法将字段初始化为默认值,而与序列化无关. (4认同)
  • 遗憾的是,他们无法简单地检测到电线上是否存在现场,并在丢失时应用合同默认规定。那本身应该与语言无关。 (2认同)
  • @MeirionHughes当然可以,但是默认值的全部意义在于应该自动设置它。如果没有构造函数,则当在应用程序代码中分配对象时,您将无法自动初始化该对象。应用程序代码作者将需要始终手动调用一些初始化函数。人们很可能会忘记。 (2认同)

Eva*_*van 5

这是一个变通方法,而不是直接回答您的问题,但我发现自己使用了 wrappers.proto 可选值,然后在我绝对必须知道这是默认值还是默认值时自己以编程方式设置默认值明确设置。

您的代码必须强制执行该值而不是生成的代码本身并不是最佳的,但是如果您拥有双方,至少它是一个可行的替代方案,而不是不知道该值是默认值还是明确设置的值,尤其是在查看时设置为 false 的布尔值。

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

原型文件

import "google/protobuf/wrappers.proto";

google.protobuf.BoolValue optional_bool = 1;
Run Code Online (Sandbox Code Playgroud)

Java代码

//load or receive message here
if( !message.hasOptionalBool() )
    message.setOptionalBool( BoolValue.newBuilder().setValue( true ) );
Run Code Online (Sandbox Code Playgroud)