c++ Protocol Buffers(protobuf)v3.0.0-alpha-2中的可选字段和约束

csga3l58  于 2023-05-30  发布在  其他
关注(0)|答案(4)|浏览(168)

我目前正在使用Google Protocol Buffers的v3.0.0-alpha-2。
据我所知,v3删除了required关键字,extensions关键字和字段的默认值,以简化proto语言。
我不明白的是proto 3中optional关键字的含义。

  • 示例:*
syntax = "proto3";

package fw.example;

message ExampleMessage {
  optional string optional_string = 1;
  string normal_string = 2;
}
  • 问题:* optional_stringnormal_string除了名称和标签之外还有什么区别?

我已经阅读了以下资源(它们似乎是protobuf v3中唯一公开可用的资源):

但是他们甚至没有提到optional关键字。

  • optional在proto 3中过时了吗,因为字段总是可选的?
  • 如果required消失了,如何用proto 3强制要求的字段?

在proto 3中,似乎无法区分未设置的字段和客户端设置为(隐式)默认值的字段。
最佳实践是将每个proto 3消息 Package 在特定于语言的类中吗?我使用的是C++,我需要确保设置了特定的字段。与proto 2相比,现在似乎必须在特定于语言的源代码中手动进行验证。
谁能告诉我,对proto 3消息应用约束但允许方案演进的最佳方法是什么?目前,我认为必须围绕proto 3消息编写一个新的API,这样客户端就不会直接处理proto 3生成的代码,而是处理自定义API代码。对吗?
也许有人能给我举个具体的例子来讨论。
我很困惑,因为在v3的发行说明中有以下说明:
我们建议新的Protocol Buffers用户使用proto 3。但是,由于API不兼容,我们一般不建议现有用户从proto 2迁移到proto 3,我们将在很长一段时间内继续支持proto 2。
如果proto 3是一条可行的路,为什么事情会变得复杂?在我看来,我现在确实需要写比proto 2更多的代码。

h5qlskok

h5qlskok1#

我的理由如下:
既然required已经过时了,那么一切都是optional。因此,没有理由使用显式关键字。
语言指南中的以下段落说明了未设置值时如何初始化:
请注意,对于标量消息字段,一旦解析了消息,就无法判断字段是否被显式设置为默认值(例如,布尔值是否被设置为false)或根本没有设置:在定义消息类型时,您应该记住这一点。
所以optional实际上意味着“如果你没有显式地设置它,我们会为你设置默认值!”
请注意,这允许他们做一些很好的优化(如果设置为默认值,则不包括连接上的值):
例如,如果您不希望默认情况下也发生某些行为,则不要使用设置为false时切换该行为的布尔值。另请注意,如果将标量消息字段设置为默认值,则不会在连接上序列化该值。

laximzn5

laximzn52#

proto3文档(“使用proto2消息类型”一节)指出,您可以使用'import'关键字导入proto2.proto文件,反之亦然。这意味着v2和v3.proto语法是兼容的,这意味着仍然支持optional和required。
我说给予看,看看会发生什么。

gfttwv5a

gfttwv5a3#

proto3的最终版本没有optional关键字。在proto3中,all fields are optional

hfwmuf9z

hfwmuf9z4#

从3.12(实验)和3.15(官方)开始,optional关键字又有了特殊的meaning。该功能是在oneof之上实现的,它支持跟踪字段的存在。
例如,以前的has_xxx()(在C++中)只为消息类型的字段生成。现在也为oneofoptional字段生成它们。
因此,如果你在消息proto中声明optional int field = 1;,那么你将能够通过使用has_field()生成的方法来区分字段被显式设置为默认值0和根本没有设置。

相关问题