Protobuf语法
什么是protobuf? 一种序列化结构数据的方式,与语言无关,与平台无关,可扩展。和json一样,但是更小更快。 V3语法介绍 举一个简单的例子,一个分页查询的请求参数,新建一个.proto文件并写入: syntax = "proto3"; message SearchRequest { string query = 1; int32 page_num = 2; int32 page_size = 3; } .proto文件的第一行指定了当前正在使用proto3语法,如果未写,proto的编译器会默认使用proto2的语法进行解析。 SearchRequest定义了三个字段,它们都有类型和名称,并且在最后给了一个唯一编号,编号的作用是在序列化后的二进制序列中标识字段。当编号为1-15的范围内时,在编码时只需要一个字节,而16-2047就需要两个字节,具体原因可以了解一下protobuf的编码原理。所以,1-15的编号最好要保留给那些最经常出现的字段。你能使用的最小编号是1,最大是$2^{29}$-1,不过你不能使用19000-19999,这些编号为protobuf的实现而预保留了,如果你使用了,是过不了编译的。 在单个.proto文件中能定义多个message类型: syntax = "proto3"; message SearchRequest { string query = 1; int32 page_num = 2; int32 page_size = 3; } message SearchResponse { repeated string data = 1; int32 total = 2; } repeated表示该字段是一个可重复值,可以理解为数组。 注释的写法: syntax = "proto3"; /* 请求结构 */ message SearchRequest { string query = 1; int32 page_num = 2; int32 page_size = 3; } /* 响应结构 */ message SearchResponse { repeated string data = 1; int32 total = 2; // 总数 } 如果我们在更新message type时,是直接删除或者注释了字段,在之后其他人来更新时可能会复用被删除或注释的字段编号,如果这时加载了相同proto的旧版本,那么就会导致一些错误。所以protobuf提供了保留字段的机制,使用reserved关键字,可以保留编号或者字段名。 message Foo { reserved 2, 15, 9 to 11; reserved "foo", "bar"; int32 foo = 2; // 会报错 } 枚举: /* 请求结构 */ message SearchRequest { string query = 1; int32 page_num = 2; int32 page_size = 3; enum Corpus { UNIVERSAL = 0; WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6; } Corpus corpus = 4; } 有一点需要注意,枚举的第一个字段值必须为0,因为这样我们就能用0作为数字编号的默认值,并且为了兼容proto2,枚举的第一个字段即为默认值。 ...