一、定义
Google推出的一种 结构化数据 的数据存储格式(类似于 XML、Json
)。
多个版本的源码地址
1、为什么选择它
优点:
- 效率高:Protobuf 以二进制格式存储数据,比如 XML 和 JSON 等文本格式更紧凑,也更快。序列化和反序列化的速度也很快。
- 跨语言支持:Protobuf 支持多种编程语言,包括 C++、Java、Python、Objective、C、Ruby、Go、PHP、Dart、JavaScript(版本3.26)。
- 清晰的结构定义:使用 Protobuf,可以清晰地定义数据的结构,这有助于维护和理解。
- 向后兼容性:你可以添加或者删除字段,而不会破坏老的应用程序。这对于长期的项目来说是非常有价值的。
缺点:
- 不直观:由于 Protobuf 是二进制格式,人不能直接阅读和修改它。这对于调试和测试来说可能会有些困难。
- 缺乏一些数据类型:例如没有内建的日期、时间类型,对于这些类型的数据,需要手动转换成可以支持的类型,如 string 或 int。
- 需要额外的编译步骤:你需要先定义数据结构,然后使用 Protobuf 的编译器将其编译成目标语言的代码,这是一个额外的步骤,可能会影响开发流程。
2、语法
Protobuf协议文件名后缀名为.proto。一个简单的Protobuf协议如下:
1 syntax="proto3";
2
3 package protobuf.addressbook;
4
5 enum PhoneType
6 {
7 MOBILE = 0;
8 HOME = 1;
9 WORK = 2;
10 }
11
12 message Person
13 {
14 optional string name = 1;
15 optional uint32 age = 2;
16 optional string email = 3;
17
18 message PhoneNumber
19 {
20 optional string number = 1;
21 optional PhoneType type = 2;
22 }
23
24 repeated PhoneNumber phone = 4;
25
26 }
27
28
29 message AddressBook
30 {
31 repeated Person person = 1;
32 }
必须指明版本:syntax = "proto3";
proto3比proto2的变化:
1、proto3比proto2支持跟多语言,语言增加 Go、Ruby、JavaNano 支持。
2、字段规则移除了"required",并把optional改名为了singlar,但是optional还可以用。
3、移除了 default 选项,在 proto2 中,可以使用 default 选项为某一字段指定默认值。在 proto3 中,字段的默认值只能根据字段类型由系统决定。也就是说,默认值全部是约定好的,而不再提供指定默认值的语法。
【在字段被设置为默认值的时候,该字段不会被序列化。这样可以节省空间,提高效率。但这样就无法区分某字段是根本没赋值,还是赋值了默认值。这在 proto3 中问题不大,但在 proto2 中会有问题。】
4、proto3默认采用 packed 编码,在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。
5、枚举类型的第一个字段必须为 0。
6、移除了对分组的支持。
7、移除了对扩展的支持,新增了 Any 类型。proto3 中新增的 Any 类型有点像 C/C++ 中的 void* 。
8、增加了 JSON 映射特性。
1)、标识符:
syntax:标识使用的protobuf是哪个版本。上面表示使用的是3.x版本。
package:标识生成目标文件的包名。在C++中表示的是命名空间。上面。表示生成的类和函数在protobuf命名空间的addressbook命令空间下。
enum:表示一个枚举类型。会在目标.h文件中自动生成一个枚举类型。
message:标识一条消息。会在目标文件中自动生成一个类。
2)、字段:
字段格式:role type name = tag [default value]
a、role有三种取值:
required:该字段必须给值,不能为空。否则message被认为是未初始化的