protobuf语法
protobuf 通常会把用户定义的结构体类型叫做一个消息,这里我们遵循惯例,统一称为消息。protobuf 消息的定义(或者称为描述)通常都写在一个以 .proto 结尾的文件中。
消息类型
syntax = "proto3"; //指定版本信息,不指定会报错
package pb; //后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
// 名字
string name = 1;
// 年龄
int32 age = 2 ;
// 邮箱
repeated string emalis =3;
// 手机
repeated string phones =4;
// repeated为关键字,作用为重复使用 一般在go语言中用切片表示
}
消息格式说明
消息由至少一个字段组合而成,类似于Go语言中的结构体,每个字段都有一定的格式:
//注释格式 注释尽量也写在内容上方
(字段修饰符)数据类型 字段名称 = 唯一的编号标签值;
- 字段名称:protobuf建议以下划线命名而非驼峰式
- 唯一的编号标签:代表每个字段的一个唯一的编号标签,在同一个消息里不可以重复。这些编号标签用与在消息二进制格式中标识你的字段,并且消息一旦定义就不能更改。需要说明的是标签在1到15范围的采用一个字节进行编码,所以通常将标签1到15用于频繁发生的消息字段。编号标签大小的范围是1到229
- 注释格式:向.proto文件添加注释,可以使用C/C++/java/Go风格的双斜杠(//) 语法格式
数据类型
.proto类型 | Go类型 | 介绍 |
---|---|---|
double | float64 | 64位浮点数 |
float | float32 | 32位浮点数 |
int32 | int32 | 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint32。 |
int64 | int64 | 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint64。 |
uint32 | uint32 | 使用可变长度编码。 |
uint64 | uint64 | 使用可变长度编码。 |
sint32 | int32 | 使用可变长度编码。符号整型值。这些比常规int32s编码负数更有效。 |
sint64 | int64 | 使用可变长度编码。符号整型值。这些比常规int64s编码负数更有效。 |
fixed32 | uint32 | 总是四字节。如果值通常大于228,则比uint 32更有效 |
fixed64 | uint64 | 总是八字节。如果值通常大于256,则比uint64更有效 |
sfixed32 | int32 | 总是四字节。 |
sfixed64 | int64 | 总是八字节。 |
bool | bool | 布尔类型 |
string | string | 字符串必须始终包含UTF - 8编码或7位ASCII文本 |
bytes | []byte | 可以包含任意字节序列 |
结构体嵌套
syntax = "proto3"; //指定版本信息,不指定会报错
package pb; //后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
// 名字
string name = 1;
// 年龄
int32 age = 2 ;
// 邮箱
repeated string emali =3;
// 手机
repeated string PhoneNumber =4;
// repeated为关键字,作用为重复使用 一般在go语言中用切片表示
}
//message为关键字,作用为定义一种消息类型可以被另外的消息类型嵌套使用
message PhoneNumber {
string number = 1;
int64 type = 2;
}
枚举类型
syntax = "proto3"; //指定版本信息,不指定会报错
package pb; //后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person {
string name = 1; //姓名
int32 age = 2; //年龄
repeated string emails = 3; //电子邮件(repeated表示字段允许重复)
repeated PhoneNumber phones = 4; //手机号
}
//enum为关键字,作用为定义一种枚举类型
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
//message为关键字,作用为定义一种消息类型可以被另外的消息类型嵌套使用
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
默认缺省值
当一个消息被解析的时候,如果被编码的信息不包含一个特定的元素,被解析的对象锁对应的域被设置位一个默认值,对于不同类型指定如下:
- 对于strings,默认是一个空string
- 对于bytes,默认是一个空的bytes
- 对于bools,默认是false
- 对于数值类型,默认是0
protobuf定义服务
如果想要将消息类型用在RPC(远程方法调用)系统中,可以在.proto
文件中定义一个RPC服务接口,protocol buffer
编译器将会根据所选择的不同语言生成服务接口代码及存根。
service SearchService {
//rpc 服务的函数名 (传入参数)返回(返回参数)
rpc Search (SearchRequest) returns (SearchResponse);
}