由于protocol Buffer 不限于编程语言,所以在编写proto文件时,指定的类型和不同编程语言的类型是一一对应的,这样在根据proto文件生成对应代码时,约束力就比较强,大概的类型对照表如下(只整理了比较常用的语言,详细请进官网):
每一种类型在没有指定值时都对应有默认值:
string: 空字符串
bytes:空byte数组
bool:false
数值型:0
枚举enum: 默认第一个枚举值,第一个值必须是0
默认值其实基本上和对应的编程语言默认值差不多一样。
3.2 常用编写方式
一般形式
通过message定义一类结构化数据,如下:
使用message定义一类数据时,其实就可以理解为在编写一个类,里面的字段就是类里面的属性。需要注意的是message中指定字段的后面数值不是字段值,而是字段名称对应的一个标识(Tag)。
嵌套自定义类型
经常会遇到这种嵌套自定义类型的场景,比如一个班级有多个学生,班级类型就需要嵌套学生,如下:
这里用到repeated来表示一个班级有多个学生,可以理解为List.
使用枚举
枚举在编程过程中肯定少不了,这里把上面的性别改为枚举,如下:
枚举类型需要注意的是第一项映射的常量值必须为0,方便设置其作为默认项,同时也是为了兼容proto2。
如果想要一个数字对应多个枚举项,可以开启允许别名的方式进行设置,如下:
文件引入
在实际开发场景中,定义的数据类型很多,放在一个文件肯定不太合适,可读性差,所以都会将其放在多个proto文件,然后通过引用多个文件即可;接下来把学生单独出来作为一个proto文件,如下:
注:在创建proto文件时,按照2.1那个步骤设置文件属性,否则不会自动生成类,如果有文件相互引用,还会编译报错。
引用第三方proto
在平时开发的时候,有些机构、社区或是大佬将常用的类进行封装,然后打包好, 我们只需要下载引用就可以愉快的使用啦;同样,proto也可以这样,如下在Student中加一个入学时间,如下:
其他类型进传送门,需要哪个,就照着上面方式使用即可。
3.3 参数字段变更注意需求变动对于开发来说是家常便饭,针对接口增加字段或修改字段都是常有的事,如果打算在原有方法修改字段,那就需要注意啦; 在通过protocol Buffer进行序列化时,是通过类似于字典的形式约定好的,其中字段后面的数字Tag至关重要,用其进行属性字段标识,学生举例如下:
// 在解析时,都是用后面的数字tag进行约定解析的 message Student{ string name=1; // 1 就代表 姓名 int32 age=2; // 2 就代表 年龄 Gender gender=3; // 3 就代表 性别 string addr=4; // 4 就代表 地址 google.protobuf.Timestamp enrollmentDate=5; //5 就代表 入学时间 }只要已经上线互相调用,如果有参数字段变动,最好是通过新增的方式,因为这样会避免双方调用因为没有同时更改参数字段造成对业务的影响。比如上面学生字段要变动,需求是:新增一个分数字段,删除年龄字段,通常会有以下方式:
方式1:将年龄字段直接改成分数字段即可
如果服务端将proto文件改成这样,客户端还没来的及改,就会造成如下情况: