此笔记基本在复述官方文档
1. .proto构成
syntax = "proto3"; //指定版本 message SearchRequest { //一下区域为field string query = 1; //等号后面的是它的编号,不是值 int32 page_number = 2; int32 result_per_page = 3; }
定义好一个message,引用.proto,就可以在C++和Java里用啦。
关于field编号:省去解析字符串的烦恼,占用空间更小,范围为1~5e8,其中19000~19999不能用。
当一些message定义相同时,可以import其他.proto文件。import public a.proto意为此文件被引用时,a.proto也被引用。但java中不支持import public。
可以为一些message加package,避免命名冲突。引用的时候就像正常语言调用过来就好了。
2. field写法
required/optional/repeated + 数据类型 +「变量名」+ 「编号」
其中repeated由于历史原因编码很慢,需要加 [packed = true]
当optional的变量没有出现时,使用它的默认值,默认值的设置例如在末尾加 [default = 10]
注释格式:和C++一样
reserved:删掉的field编号。防止新版本已删除的编号在调用老版本时再次被使用,造成数据泄露等问题。
这里插一句message更新,更新直接改就行,旧版本会自动忽略新增内容,删除记得加关键字。
field内容可以为其他message。
extension字段:留给第三方插件的字段。
可以定义一个map,就是STL里类似的那个map。
3. Enum用法
当定义一个message的时候,有时我们希望其中一些field的值是规定的一系列值中的一个,这时我们用enum来列举可能的值,编号从0开始,例如:
message SearchRequest { required string query = 1; optional int32 page_number = 2; optional int32 result_per_page = 3 [default = 10]; enum Corpus { UNIVERSAL = 0; WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6; } optional Corpus corpus = 4 [default = UNIVERSAL]; }
当其值可以为其中多个的组合时,需要加上 option allow_alias = true;
保留值和上面差不多。
4. 嵌套使用
message里可以套message,当多一组数据不以message的形式存在时,可以用group。
5. Oneof用法
当一个message可能有多种数据构成时,每种可能的数据构成用Oneof来表示。多个Oneof在最终编码时只使用一个空间,也就是只能操作一个字段。
message SampleMessage { oneof test_oneof { string name = 4; SubMessage sub_message = 9; } }
6. Services
要向别的服务器申请服务时调用,然后收发message。
7. Options
一些编译项,可能没作用,类似O2、O3这种。还有自定义选项,以后用到了再补充。
8. 编译使用
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR path/to/file.proto
IMPORT_PATH:需要用.proto的目录