1. 指明版本

.proto文件中使用proto3的语法需要在开头声明:

syntax="proto3"

2. 定义消息



syntax = "proto3";
 
message AddUserReq {
  string name = 1;
  string password = 2;
  sint64 group_id = 3;
}



消息的字段声明由4部分构成:字段修饰符 字段类型 字段名称 = 标志号

1) 字段修饰符

* singular : 默认值,该字段可以出现0次或者1次(不能超过1次)。

* repeated : 该字段可以重复任意多次(包括0次)。proto3中,repeated默认使用packed。

proto3中在语法层将required移除,singular是由optional改名而来。

2) 字段类型

.proto type

Notes

C++ type

Go type

double

 

double

float64

float

 

float

float32

int32

使用变长编码,对于负值的效率很低,如果该域有可能有负值,使用sint64替代

int32

int32

int64

 

int64

int64

uint32

使用变长编码

uint32

uint32

uint64

使用变长编码

uint64

uint64

sint32

使用变长编码,处理负值时比int32高效

int32

int32

sint64

使用变长编码,处理负值时比int64高效

int64

int64

fixed32

固定4个字节,如果数值总是比228大,此类型比uint32高效

uint32

uint32

fixed64

固定8个字节,如果数值总是比256大,此类型比uint64高效

uint64

uint64

sfixed32

固定4个字节

int32

int32

sfixed64

固定8个字节

int64

int64

bool

 

bool

bool

string

一个字符串,必须是UTF-8编码或7-bit ASCII编码

string

string

bytes

可能包含任意顺序的字节数据

string

[]byte

默认值:

* string类型默认值是空字符串,不是null

* bytes类型默认是空bytes

* bool类型默认值是false

* 数字类型默认值是0

* 枚举类型默认值是第一个枚举值,即0

* repeated修饰的字段,默认值是空(在对应的编程语言中通常是一个空的list) 

3) 标志号

每一个被定义在消息中的字段都会被分配一个唯一的标量,这些标量用于标志定义在二进制消息格式中的属性。标量一旦被定义就不允许在使用过程中再次被改变。

1~15的标志号在编码的时候会占用一个字节,16~2047的标志号则占用两个字节,所以应该为频繁出现的消息元素保留1~15的标志号。

保留标识符(reserved)可以避免其他人在未来使用不该使用的标志号。



message Foo {
  reserved 2, 15, 9 to 11;
  reserved "foo", "bar";
}



 

3. 枚举



message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }
  Corpus corpus = 4;
}


Corpus枚举类型的第一个枚举值是0,每一个枚举值定义都会与一个常量映射,而这些常量的第一个常量必须为0。

 

4. 导入其它.proto中定义的消息

import "test/result.proto";

5. 包

可以为.proto文件指定包名,防止消息名冲突。

6. 服务定义

如果想在RPC中使用已经定义好的消息类型,可以在.proto文件中定一个消息服务接口,protocol buffer编译器会生成对应语言的接口代码。


service SearchService {
    //  方法名  方法参数                 返回值
    rpc Search(SearchRequest) returns (SearchResponse); 
}