多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 语法 ### 格式的定义 `[ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"` 或 `type fieldName "=" fieldNumber` ### 版本定义 ``` syntax = "proto3"; // or syntax = "proto2"; ``` ### package 定义包名 ``` package foo.bar; ``` ### repeated 允许重复 .proto ``` message Person { string name = 1; int32 id = 2; repeated string email = 3; } ``` demo.go ``` p := &Person{ Name: "smallnest", Id: 9527, Email: []string{"test@example.com"}, } ``` ### option option可以用在proto的scope中,或者message、enum、service的定义中。 可以是Protobuf定义的option,或者自定义的option。 option的定义格式是`"option" optionName "=" constant ";"` 比如: `option java_package = "com.example.foo"; ` 一些Protobuf定义的option: ``` java_package java_multiple_files java_outer_classname optimize_for cc_enable_arenas objc_class_prefix deprecated go_package ``` ### **普通字段** > [官网类型对应其他语言](https://developers.google.com/protocol-buffers/docs/proto3#scalar) * 数字类型: double、float、int32、int64、uint32、uint64、sint32、sint64: 存储长度可变的浮点数、整数、无符号整数和有符号整数 * 存储固定大小的数字类型:fixed32、fixed64、sfixed32、sfixed64: 存储空间固定 * 布尔类型: bool * 字符串: string * bytes: 字节数组 * messageType: 消息类型 * enumType:枚举类型 ![UTOOLS1577338933390.png](http://yanxuan.nosdn.127.net/f1ec32b0cdda86ac5476f56552e0925e.png) ![UTOOLS1577338958932.png](http://yanxuan.nosdn.127.net/3c3a41d3081d73b48d77829a44a16720.png) ![](https://img.kancloud.cn/18/83/18833840da725c74b38f8a7925a02b2f_1342x1248.png) ### Oneof 如果你有一组字段,同时最多允许这一组中的一个字段出现,就可以使用`Oneof`定义这一组字段,这有点Union的意思,但是Oneof允许你设置零各值。 因为proto3没有办法区分正常的值是否是设置了还是取得缺省值(比如int64类型字段,如果它的值是0,你无法判断数据是否包含这个字段,因为0几可能是数据中设置的值,也可能是这个字段的零值),所以你可以通过Oneof取得这个功能,因为Oneof有判断字段是否设置的功能。 ``` syntax = "proto3"; package abc; message OneofMessage { oneof test_oneof { string name = 4; int64 value = 9; } } ``` >`oneof`字段不能同时使用`repeated`。 ### map类型 `map<int64,string> values = 1; ` ### Reserved 也就是忽略某些字段,可以通过字段编号范围或者字段名称指定保留的字段 ``` syntax = "proto3"; package abc; message AllNormalypes { reserved 2, 4 to 6; reserved "field14", "field11"; double field1 = 1; // float field2 = 2; int32 field3 = 3; // int64 field4 = 4; // uint32 field5 = 5; // uint64 field6 = 6; sint32 field7 = 7; sint64 field8 = 8; fixed32 field9 = 9; fixed64 field10 = 10; // sfixed32 field11 = 11; sfixed64 field12 = 12; bool field13 = 13; // string field14 = 14; bytes field15 = 15; } ``` > 声明保留的字段你就不要再定义了,需注释,否则编译的时候会出错。 ### 枚举类型 避免在同一个package定义重名的枚举字段 ``` enum EnumAllowingAlias { option allow_alias = true; UNKNOWN = 0; STARTED = 1; RUNNING = 1; } enum EnumNotAllowingAlias { UNKNOWN2 = 0; STARTED2 = 1; // RUNNING = 1; } ``` > 设置 `allow_alias` 允许重复字段编号 如`STARTED`和`RUNNING ` > **第一个枚举值必须是0**,而且必须定义 枚举类型定义到message中 ``` 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; } ``` ### 使用其它类型 在SearchResponse 中调用 Result 类型 ``` message SearchResponse { repeated Result results = 1; } message Result { string url = 1; string title = 2; repeated string snippets = 3; } ``` ### 嵌套类型 ``` message SearchResponse { message Result { string url = 1; string title = 2; repeated string snippets = 3; } repeated Result results = 1; } ``` ### Any Any字段允许你处理嵌套数据,并不需要它的proto定义。一个Any以bytes呈现序列化的消息,并且包含一个URL作为这个类型的唯一标识和元数据 ``` import "google/protobuf/any.proto"; message ErrorStatus { string message = 1; repeated google.protobuf.Any details = 2; } ```