我目前正在使用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_string
和normal_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更多的代码。
4条答案
按热度按时间h5qlskok1#
我的理由如下:
既然
required
已经过时了,那么一切都是optional
。因此,没有理由使用显式关键字。语言指南中的以下段落说明了未设置值时如何初始化:
请注意,对于标量消息字段,一旦解析了消息,就无法判断字段是否被显式设置为默认值(例如,布尔值是否被设置为false)或根本没有设置:在定义消息类型时,您应该记住这一点。
所以
optional
实际上意味着“如果你没有显式地设置它,我们会为你设置默认值!”请注意,这允许他们做一些很好的优化(如果设置为默认值,则不包括连接上的值):
例如,如果您不希望默认情况下也发生某些行为,则不要使用设置为false时切换该行为的布尔值。另请注意,如果将标量消息字段设置为默认值,则不会在连接上序列化该值。
laximzn52#
proto3文档(“使用proto2消息类型”一节)指出,您可以使用'import'关键字导入proto2.proto文件,反之亦然。这意味着v2和v3.proto语法是兼容的,这意味着仍然支持optional和required。
我说给予看,看看会发生什么。
gfttwv5a3#
proto3的最终版本没有
optional
关键字。在proto3中,all fields are optional。hfwmuf9z4#
从3.12(实验)和3.15(官方)开始,
optional
关键字又有了特殊的meaning。该功能是在oneof
之上实现的,它支持跟踪字段的存在。例如,以前的
has_xxx()
(在C++中)只为消息类型的字段生成。现在也为oneof
和optional
字段生成它们。因此,如果你在消息proto中声明
optional int field = 1;
,那么你将能够通过使用has_field()
生成的方法来区分字段被显式设置为默认值0和根本没有设置。