Protobuf语法 · Go语言中文文档


本站和网页 https://www.topgoer.com/%E5%BE%AE%E6%9C%8D%E5%8A%A1/gRPC/Protobuf%E8%AF%AD%E6%B3%95.html 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Protobuf语法 · Go语言中文文档
前景
开发环境
Go的安装
配置GOPATH
编辑器
Git安装
第一个go程序
Go基础
Go语言的主要特征
Golang内置类型和函数
Init函数和main函数
命令
运算符
下划线
变量和常量
基本类型
数组Array
切片Slice
Slice底层实现
指针
Map
Map实现原理
结构体
流程控制
条件语句if
条件语句switch
条件语句select
循环语句for
循环语句range
循环控制Goto、Break、Continue
函数
函数定义
参数
返回值
匿名函数
闭包、递归
延迟调用(defer)
异常处理
单元测试
压力测试
方法
方法定义
匿名字段
方法集
表达式
自定义error
面向对象
匿名字段
接口
网络编程
互联网协议介绍
socket编程
socket图解
TCP编程
UDP编程
TCP黏包
http编程
WebSocket编程
并发编程
并发介绍
Goroutine
runtime包
Channel
Goroutine池
定时器
select
并发安全和锁
Sync
原子操作(atomic包)
GMP 原理与调度
爬虫小案例
数据操作
go操作MySQL
go操作MySQL
Insert操作
Select操作
Update操作
Delete操作
MySQL事务
go操作Redis
Redis介绍
链接Redis
String类型Set、Get操作
String批量操作
设置过期时间
List队列操作
Hash表
Redis连接池
go操作ETCD
ETCD介绍
操作ETCD
zookeeper
基本操作测试
简单的分布式server
Zookeeper命令行使用
go操作kafka
Kafka介绍
Kafka深层介绍
Kafka的安装
操作Kafka
go操作RabbitMQ
RabbitMQ介绍
RabbitMQ安装
Simple模式
Work模式
Publish模式
Routing模式
Topic模式
go操作ElasticSearch
ElasticSearch介绍
Elasticsearch安装
Kibana安装
操作ElasticSearch
NSQ
安装
生产者
消费者
GORM
入门指南
概览
模型定义
惯例
连接数据库
CRUD 接口
创建
查询
更新
删除
关联
Belongs To
Has One
Has Many
Many To Many
关联
预加载
教程
链式操作
错误处理
钩子
事务
数据库迁移
原生 SQL 和 SQL 生成器
通用数据库接口
高级主题
复合主键
创建插件
GORM Dialects
自定义Logger
更新日志
Gorm用法介绍
xorm
go操作memcached
常用标准库
fmt
Time
Flag
Log
IO操作
Strconv
Template
Http
Context
数据格式
反射
beego框架
简介
beego 安装
beego 安装升级
bee工具的使用
快速入门
新建项目
路由设置
Controller运行机制
Model逻辑
View编写
静态文件处理
beego的MVC架构介绍
controller设计
参数配置
路由设置
控制器函数
XSRF过滤
请求数据处理
Session控制
过滤器
Flash数据
URL构建
多种格式数据输出
表单数据验证
错误处理
日志处理
model设计
概述
ORM使用
CRUD操作
高级查询
原生SQL查询
构造查询
事务处理
模型定义
命令模式
测试用例
自定义字段
FAQ
view设计
模板语法指南
模板处理
模板函数
静态文件处理
模板分页处理
beego的模块设计
Session模块
Grace模块
Cache模块
Logs模块
Httplib模块
Context模块
Toolbox模块
Config模块
I18n模块
beego高级编程
进程内监控
API自动化文档
应用部署
独立部署
Supervisor部署
Nginx部署
Apache部署
beego第三方库
应用例子
在线聊天室
短域名服务
Todo列表
beego实用库
验证码
分页
FAQ
gin框架
简介
gin路由
基本路由
Restful风格的API
API参数
URL参数
表单参数
上传单个文件
上传多个文件
routes group
路由原理
路由拆分与注册
gin 数据解析和绑定
Json 数据解析和绑定
表单数据解析和绑定
URI数据解析和绑定
gin 渲染
各种数据格式的响应
HTML模板渲染
重定向
同步异步
gin 中间件
全局中间件
Next()方法
局部中间件
中间件练习
中间件推荐
会话控制
Cookie介绍
Cookie的使用
Cookie练习
Cookie的缺点
Sessions
参数验证
结构体验证
自定义验证
多语言翻译验证
其他
日志文件
Air实时加载
gin验证码
生成解析token
权限管理
gin 源码解读
net/http的大概流程
揭开gin的神秘面纱
gin牛逼的context
gin的路由算法
Iris框架
关于
安装
开始使用
Host
带有TLS的自动公共域名
配置
路由
路径参数类型
反向查询
中间件
处理HTTP错误
子域名
包装路由器
重写Context
Context方法
HTTP Method Override
API版本控制
内容协商
响应记录器
HTTP Referer
请求认证
URL查询参数
表单
模型验证
缓存
文件服务
视图
Cookies
Sessions
Websockets
MVC
测试
Echo框架
微服务
认识微服务
微服务生态
微服务详解
RPC
RPC系统文档
Raft
gRPC
安装
gRPC简介
Protobuf⇢Go转换
Protobuf语法
小案例
OpenSSL安装
认证
拦截器
内置Trace
HTTP网关
Go Micro入门
Go Micro接口详解
Go Micro文档1.x
Go Micro文档2.x
Go高级
快速排序算法
堆排序算法
冒泡排序算法
二分查找方法
选择排序算法
基数排序算法
拓扑排序
字符串匹配
二叉搜索树
散列表
链表
跳跃表
字典树
向量空间
插件库
跨平台交叉编译
文件上传
依赖管理
高效读取配置信息
实时读取文件内容
加密解密
哈希算法
加密解密
md5
base64
sha
hmac
跨域
系统性能数据gopsutil库
pprof性能调优
数据绑定结构体
查询结果反射结构体
form数据绑定结构体
验证器
验证码
流量控
发邮件
页面静态化
文件监控
雪花算法
函数验证中间键
封装websocket
生成PDF
获取HTTP请求的IP地址
JSON Web令牌
检查切片中是否存在元素
查看图片主要颜色
判断字符串开头
字符串中解析日期
压缩解压文件
PDF转JPG
Sessions
markdown解析库
选项设计模式
运行系统命令和二进制文件
proxy转发
字符串数组排序
带进度条大文件下载
gjson
解决中文乱码
二维码
Yaml编码和解码
中文分词
权限管理
Swaggo
网页截图
汉字转拼音
CLI框架
Google 翻译API
限流器
缓存
支付插件
获取https过期时间
获取服务器配置
热重启
原生中间件
设置https
项目
github库地址
TCP扫描器
定时任务
cron
gocron
基于角色的访问控制框架
uuid
支付宝支付
微信支付
微信公众号开发
爬虫小案例
千万数据过滤
需求
读入数据
数据清洗
省份划分
go-admin
go-vue-admin
go-admin
log
Logger
Zap Logger
日志切割归档
聊天室小案例
性能压测工具wrk
gcc安装
开源仓库
go学习线路图
音频和音乐
身份验证和OAuth
机器人相关
标准CLI
构建用户界面库
配置
持续集成
CSS预处理器
数据结构
数据库
数据库
数据库架构迁移
数据库工具
SQL查询构建器
数据库驱动
关系数据库
NoSQL数据库
搜索和分析数据库
多个后端
日期和时间
分布式系统
电子邮件
嵌入式脚本语言
错误处理
文件
金融
Forms
功能性
游戏开发
生成与泛型
地理位置
编译器
Goroutines
图形界面
图片
物联网
工作计划
JSON格式
Logging
机器学习
实现消息传递
微软办公软件
依赖注入
项目布局
Strings
其他
自然语言处理
网络
HTTP客户端
OpenGL
ORM
包管理
性能
查询语言
资源嵌入
科学与数据分析
安全
序列化
服务器应用
流处理
模板引擎
测试
文字处理
第三方API
实用工具
UUID
验证方式
版本控制
视频
Web框架
中间件
路由器
视窗
XML格式
代码分析
编辑器插件
硬件
go生成工具
go工具
DevOps工具
持续更新...
其他
Golang 58个坑
资料下载
零碎知识点
面试题
go中文标准文档
go专家编程
go设计模式
go公众号开发
关于
更新列表
持续更新中...
豫ICP备20001572号
Protobuf语法
1. Protobuf语法1.1.1. 基本规范1.1.2. 字段规则1.1.3. service如何定义1.1.4. Message如何定义1.1.5. 添加更多Message类型1.1.6. 如何使用其他Message1.1.7. Message嵌套的使用1.1.8. proto3的Map类型1.1.9. .proto文件编译1.1.10. import导入定义1.1.11. 包的使用1. Protobuf语法
1.1.1. 基本规范
文件以.proto做为文件后缀,除结构定义外的语句以分号结尾
结构定义可以包含:message、service、enum
rpc方法定义结尾的分号可有可无
Message命名采用驼峰命名方式,字段命名采用小写字母加下划线分隔方式 message SongServerRequest {
required string song_name = 1;
Enums类型名采用驼峰命名方式,字段命名采用大写字母加下划线分隔方式 enum Foo {
FIRST_VALUE = 1;
SECOND_VALUE = 2;
Service与rpc方法名统一采用驼峰式命名
1.1.2. 字段规则
字段格式:限定修饰符 | 数据类型 | 字段名称 | = | 字段编码值 | [字段默认值]
限定修饰符包含 required\optional\repeated
Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃
Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡
Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值
数据类型
Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型
.proto
C++
Java
Python
Go
Ruby
C#
double
double
double
float
float64
Float
double
float
float
float
float
float32
Float
float
int32
int32
int
int
int32
Fixnum or Bignum
int
int64
int64
long
ing/long[3]
int64
Bignum
long
uint32
uint32
int[1]
int/long[3]
uint32
Fixnum or Bignum
uint
uint64
uint64
long[1]
int/long[3]
uint64
Bignum
ulong
sint32
int32
int
intj
int32
Fixnum or Bignum
int
sint64
int64
long
int/long[3]
int64
Bignum
long
fixed32
uint32
int[1]
int
uint32
Fixnum or Bignum
uint
fixed64
uint64
long[1]
int/long[3]
uint64
Bignum
ulong
sfixed32
int32
int
int
int32
Fixnum or Bignum
int
sfixed64
int64
long
int/long[3]
int64
Bignum
long
bool
bool
boolean
boolean
bool
TrueClass/FalseClass
bool
string
string
String
str/unicode[4]
string
String(UTF-8)
string
bytes
string
ByteString
str
[]byte
String(ASCII-8BIT)
ByteString
+ N 表示打包的字节并不是固定。而是根据数据的大小或者长度
+ 关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高
字段名称
字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的
protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName
字段编码值
有了该值,通信双方才能互相识别对方的字段,相同的编码值,其限定修饰符和数据类型必须相同,编码值的取值范围为 1~2^32(4294967296)
其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低,所以建议把经常要传递的值把其字段编码设置为1-15之间的值
1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用
字段默认值
当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端
1.1.3. service如何定义
如果想要将消息类型用在RPC系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器会根据所选择的不同语言生成服务接口代码
例如,想要定义一个RPC服务并具有一个方法,该方法接收SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse) {}
生成的接口代码作为客户端与服务端的约定,服务端必须实现定义的所有接口方法,客户端直接调用同名方法向服务端发起请求,比较麻烦的是,即便业务上不需要参数也必须指定一个请求消息,一般会定义一个空message
1.1.4. Message如何定义
一个message类型定义描述了一个请求或响应的消息格式,可以包含多种类型字段
例如定义一个搜索请求的消息格式,每个请求包含查询字符串、页码、每页数目
字段名用小写,转为go文件后自动变为大写,message就相当于结构体
syntax = "proto3";
message SearchRequest {
string query = 1; // 查询字符串
int32 page_number = 2; // 页码
int32 result_per_page = 3; // 每页条数
首行声明使用的protobuf版本为proto3
SearchRequest 定义了三个字段,每个字段声明以分号结尾,.proto文件支持双斜线 // 添加单行注释
1.1.5. 添加更多Message类型
一个.proto文件中可以定义多个消息类型,一般用于同时定义多个相关的消息,例如在同一个.proto文件中同时定义搜索请求和响应消息
syntax = "proto3";
// SearchRequest 搜索请求
message SearchRequest {
string query = 1; // 查询字符串
int32 page_number = 2; // 页码
int32 result_per_page = 3; // 每页条数
// SearchResponse 搜索响应
message SearchResponse {
...
1.1.6. 如何使用其他Message
message支持嵌套使用,作为另一message中的字段类型
message SearchResponse {
repeated Result results = 1;
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
1.1.7. Message嵌套的使用
支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息
内部声明的message类型名称只可在内部直接使用
message SearchResponse {
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
repeated Result results = 1;
另外,还可以多层嵌套
message Outer { // Level 0
message MiddleAA { // Level 1
message Inner { // Level 2
int64 ival = 1;
bool booly = 2;
message MiddleBB { // Level 1
message Inner { // Level 2
int32 ival = 1;
bool booly = 2;
1.1.8. proto3的Map类型
proto3支持map类型声明
map<key_type, value_type> map_field = N;
message Project {...}
map<string, Project> projects = 1;
键、值类型可以是内置的类型,也可以是自定义message类型
字段不支持repeated属性
1.1.9. .proto文件编译
通过定义好的.proto文件生成Java, Python, C++, Go, Ruby, JavaNano, Objective-C, or C# 代码,需要安装编译器protoc
当使用protocol buffer编译器运行.proto文件时,编译器将生成所选语言的代码,用于使用在.proto文件中定义的消息类型、服务接口约定等。不同语言生成的代码格式不同:
C++: 每个.proto文件生成一个.h文件和一个.cc文件,每个消息类型对应一个类
Java: 生成一个.java文件,同样每个消息对应一个类,同时还有一个特殊的Builder类用于创建消息接口
Python: 姿势不太一样,每个.proto文件中的消息类型生成一个含有静态描述符的模块,该模块与一个元类metaclass在运行时创建需要的Python数据访问类
Go: 生成一个.pb.go文件,每个消息类型对应一个结构体
Ruby: 生成一个.rb文件的Ruby模块,包含所有消息类型
JavaNano: 类似Java,但不包含Builder类
Objective-C: 每个.proto文件生成一个pbobjc.h和一个pbobjc.m文件
C#: 生成.cs文件包含,每个消息类型对应一个类
1.1.10. import导入定义
可以使用import语句导入使用其它描述文件中声明的类型
protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同,例如import "others.proto";
protocol buffer编译器会在 -I / --proto_path参数指定的目录中查找导入的文件,如果没有指定该参数,默认在当前目录中查找
1.1.11. 包的使用
在.proto文件中使用package声明包名,避免命名冲突
syntax = "proto3";
package foo.bar;
message Open {...}
在其他的消息格式定义中可以使用包名+消息名的方式来使用类型,如
message Foo {
...
foo.bar.Open open = 1;
...
在不同的语言中,包名定义对编译后生成的代码的影响不同
C++ 中:对应C++命名空间,例如Open会在命名空间foo::bar中
Java 中:package会作为Java包名,除非指定了option jave_package选项
Python 中:package被忽略
Go 中:默认使用package名作为包名,除非指定了option go_package选项
JavaNano 中:同Java
C# 中:package会转换为驼峰式命名空间,如Foo.Bar,除非指定了option csharp_namespace选项
results matching ""
No results matching ""