4.4 protobuf语法

protobuf 通常会把用户定义的结构体类型叫做一个消息,这里我们遵循惯例,统一称为消息。protobuf 消息的定义(或者称为描述)通常都写在一个以 .proto 结尾的文件中。

A) 一个简单的例子
  1. syntax = "proto3"; //指定版本信息,不指定会报错
  2. package pb; //后期生成go文件的包名
  3. //message为关键字,作用为定义一种消息类型
  4. message Person {
  5. string name = 1; //姓名
  6. int32 age = 2; //年龄
  7. repeated string emails = 3; //电子邮件(repeated表示字段允许重复)
  8. repeated PhoneNumber phones = 4; //手机号
  9. }
  10. //enum为关键字,作用为定义一种枚举类型
  11. enum PhoneType {
  12. MOBILE = 0;
  13. HOME = 1;
  14. WORK = 2;
  15. }
  16. //message为关键字,作用为定义一种消息类型可以被另外的消息类型嵌套使用
  17. message PhoneNumber {
  18. string number = 1;
  19. PhoneType type = 2;
  20. }
B) 消息格式说明

消息由字段组成,每个消息的字段格式为:

(字段修饰符 +)数据类型 + 字段名称 + 唯一的编号标签值;

  • 字段名称:蛇形或者驼峰

  • 唯一的编号标签:代表每个字段的一个唯一的编号标签,在同一个消息里不可以重复。这些编号标签用与在消息二进制格式中标识你的字段,并且消息一旦定义就不能更改。需要说明的是标签在1到15范围的采用一个字节进行编码,所以通常将标签1到15用于频繁发生的消息字段。编号标签大小的范围是1到229

  • 注释格式:向.proto文件添加注释,可以使用C/C++/java/Go风格的双斜杠(//) 语法格式

C) 数据类型
.proto TypeGo TypeNotes
doublefloat6464位浮点数
floatfloat3232位浮点数
int32int32使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代
uint32uint32使用变长编码
uint64uint64使用变长编码
sint32int32使用变长编码,这些编码在负值时比int32高效的多
sint64int64使用变长编码,有符号的整型值。编码时比通常的int64高效。
fixed32uint32总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。
fixed64uint64总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。
sfixed32int32总是4个字节
sfixed32int32总是4个字节
sfixed64int64总是8个字节
boolbool
stringstring一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。
bytes[]byte可能包含任意顺序的字节数据。

更多详情请看:https://developers.google.com/protocol-buffers/docs/encoding

D) 默认缺省值

当一个消息被解析的时候,如果被编码的信息不包含一个特定的元素,被解析的对象锁对应的域被设置位一个默认值,对于不同类型指定如下:

  • 对于strings,默认是一个空string

  • 对于bytes,默认是一个空的bytes

  • 对于bools,默认是false

  • 对于数值类型,默认是0