语法
最后更新于:2022-04-02 02:57:15
[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://docs.gechiui.com/gc-content/uploads/sites/kancloud/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 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;
}
```
';