详解Golang ProtoBuf的基本语法总结

目录
  • 前言
  • 基本规范
  • 基本语法
    • package定义包
    • import 导入包
    • 定义Message
    • 定义Service

前言

最近项目是采用微服务架构开发的,各服务之间通过gPRC调用,基于ProtoBuf序列化协议进行数据通信,因此接触学习了Protobuf,本文会对Protobuf的语法做下总结,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

gRPC的调用模型如下:

基本规范

文件以.proto做为文件后缀,除结构定义外的语句以分号结尾。

rpc方法定义结尾的分号可有可无。

Message命名采用驼峰命名方式,字段命名采用小写字母加下划线分隔方式。

基本语法

首先看一个简单的示例:

/*
头部相关声明
*/
syntax = "proto3"; // 语法版本为protobuf3.0
package user; // 定义包名,可以为.proto文件指定包名,防止消息名冲突。
import "common.proto"; // 导入common.proto
option go_package = ".;proto";

//服务
service User {
rpc SayHello (SayHelloRequest) returns (SayHelloResponse) {}
}

//定义请求消息体
message SayHelloRequest {
string name = 1;
int64  role = 2;
}

//定义响应消息体
message SayHelloResponse {
string message = 1;
}

.proto文件的第一个非注释行用于指定语法版本,默认为“proto2”;

package定义包

可以为.proto文件指定包名,防止消息名冲突。

import 导入包

可以通过import导入其它.proto中定义的消息;常用于导入一些公共的信息。

正常情况下只能使用直接导入的proto文件的定义;如果需要使用多级import导入的文件,import 可以使用 public 属性。示例如下:

a.proto

import public "common.proto"; // 注意此处使用的是import public
import "c.proto";

b.proto

import "a.proto";

在b.proto中可以用common.proto中定义的内容,但是不能用c中的定义的内容。

定义Message

定义message使用“message”关键字,消息的字段声明由4部分构成:字段修饰符 字段类型 字段名称 = 标志号。

格式如下:

message 消息名称 {

[字段修饰符] 字段类型 字段名称 = 标志号;

}

字段修饰符

  • singular:默认值,该字段可以出现0次或者1次(不能超过1次);
  • repeated:该字段可以重复任意多次(包括0次);

我们可以使用repeated关键字来表示动态数组,示例如下:

message User {
	repeated int64 id = 1;
}

在请求的时候我们可以传[]int64{1, 2, 3, 4}

字段类型

关于字段类型,这里列举几个常用的,其它的如果有需要可以直接网上搜。

类型 备注
string 字符串
double 64位浮点型
float 32位浮点型
int32、int64 整型
bool 布尔型
uint32、uint64 无符号整型
sint32、sint64 有符号的整形

字段编号

每个字段都有一个编号,这些编号是 唯一的。该编号会用来识别二进制数据中的字段。编号在1-15范围内可以用一个字节编码表示,在16-2047范围用两个字节表示,所以将15以内得编号留给频繁出现的字段可以节省空间。

枚举类型

在定义消息类型时,我们有可能会为某个字段预定义值的一个列表,我们可以通过enum来添加一个枚举,为每个可能的值添加一个常量。示例如下:

message UserRequest {
    string name = 1;
    // 定义性别枚举
    enum Gender {
        UNKNOWN = 0;
        MAN = 1;
        WOMAN = 2;
    }
    // 定义一个枚举字段
    Gender gender = 2;
}

注意:所有枚举定义都需要包含一个常量映射到0并且作为定义的首行。

嵌套类型

嵌套类型,也就是字面意思,在 message 消息体中,又嵌套了其它的 message 消息体,一共有两种模式,如下:

syntax = "proto3";
message UserResponse {
    message User {
        int64 id = 1;
        string name = 2;
    }
    repeated User users = 1;
} 

如果在外部消息之外使用内部消息,则需要使用“outermsg.innermsg”的方式,如,需要在UserResponse外使用User, 则应该使用:

UserResponse.User

Map类型

在返回列表的时候,map类型经常用到,可以使用map关键字可以创建一个映射,语法如:

map<key_type, value_type> map_field = N;
  • key_type 只能是整数或字符串,enum不能作为key_type;
  • value_type 是除了映射(map)意外的任意类型;

示例:

message User {
    int64 id = 1;
    string name = 2;
}

map[int64, User] users = 1;

定义Service

如果想在RPC中使用已经定义好的消息类型,可以在.proto文件中定一个消息服务接口,使用service关键字进行服务定义,如:

service User {
rpc SayHello (SayHelloRequest) returns (SayHelloResponse) {}
}

到此这篇关于详解Golang ProtoBuf的基本语法总结的文章就介绍到这了,更多相关Golang ProtoBuf内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在go语言中安装与使用protobuf的方法详解

    简介 本文主要给大家介绍了关于go语言安装使用protobuf的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. protobuf是Google开发出来的一个语言无关.平台无关的数据序列化工具,在rpc或tcp通信等很多场景都可以使用.通俗来讲,如果客户端和服务端使用的是不同的语言,那么在服务端定义一个数据结构,通过protobuf转化为字节流,再传送到客户端解码,就可以得到对应的数据结构.这就是protobuf神奇的地方.并且,它的通信效率极高,"一条消息数据,用pr

  • Go语言中的数据格式(json、xml 、msgpack、protobuf)使用总结

    在分布式的系统中,因为涉及到数据的传输,所以一定会进行数据的交换,此时就要定义数据交换的格式,例如二进制.Json.Xml等等.本篇文章就是总结一下常用的几种数据格式. 一.Json格式 如果想使用Json数据格式,可以借助于encoding/json这个包. 利用json包里的 json.Marshal(xxx) 和 json.Unmarshal(data, &xxx) 进行序列化和反序列化. 下面举个例子: package main import ( "encoding/json&q

  • golang 微服务之gRPC与Protobuf的使用

    RPC是什么? 所谓RPC(remote procedure call 远程过程调用)框架实际是提供了一套机制,使得应用程序之间可以进行通信,而且也遵从server/client模型.使用的时候客户端调用server端提供的接口就像是调用本地的函数一样. gRPC是什么? 与许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法.默认情况下,gRPC使用协议缓冲区作为接口定义语言(IDL)来描述服务接口和有效负载消息的结构. gRPC有什么好处以及在什么场景下

  • Goland中Protobuf的安装、配置和使用

    目录 引言 1.安装protobuf编译器 2.下载protobuf的golang支持库,安装protoc-gen-go 3.protobuf使用示例 引言 本文记录了mac环境下protobuf的编译安装,并通过一个示例来演示proto自动生成go代码. 本文使用的mac os 12.3系统,不建议使用homebrew安装,系统版本太高,会安装报错,所以自己下载新版压缩包编译构建安装. 1.安装protobuf编译器 在 官方github选择适合自己系统的Proto编译器程序进行下载安装 本文

  • 详解Golang ProtoBuf的基本语法总结

    目录 前言 基本规范 基本语法 package定义包 import 导入包 定义Message 定义Service 前言 最近项目是采用微服务架构开发的,各服务之间通过gPRC调用,基于ProtoBuf序列化协议进行数据通信,因此接触学习了Protobuf,本文会对Protobuf的语法做下总结,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助. gRPC的调用模型如下: 基本规范 文件以.proto做为文件后缀,除结构定义外的语句以分号结尾. rpc方法定义结尾的分号可有可无. Messag

  • 详解Golang Iris框架的基本使用

    Iris介绍 编写一次并在任何地方以最小的机器功率运行,如Android.ios.Linux和Windows等.它支持Google Go,只需一个可执行的服务即可在所有平台. Iris以简单而强大的api而闻名. 除了Iris为您提供的低级访问权限. Iris同样擅长MVC. 它是唯一一个拥有MVC架构模式丰富支持的Go Web框架,性能成本接近于零. Iris为您提供构建面向服务的应用程序的结构. 用Iris构建微服务很容易. 1. Iris框架 1.1 Golang框架   Golang常用

  • 详解Golang语言中的interface

    interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface.任意类型都实现了空interface(也就是包含0个method的interface),空interface可以存储任意类型的值.interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口. go version go1.12 package main import ( "fmt" ) // 定义struct type Hu

  • 详解golang中的method

    什么是method(方法)?method是函数的另外一种形态,隶属于某个类型的方法. method的语法: func (r Receiver) funcName (parameters) (result) receiver可以看作是method的第一个参数,method并且支持继承和重写. Go中虽没有class,但依旧有method 通过显示说明receiver来实现与某个类型的结合 只能为同一个包中的类型定义方法 receiver可以是类型的值或者指针 不存在方法重载 可以使用值或指针来调用

  • 详解Go与PHP的语法对比

    概述 Go 是由 Google 设计的一门静态类型的编译型语言.它有点类似于 C,但是它包含了更多的优点,比如垃圾回收.内存安全.结构类型和并发性.它的并发机制使多核和网络机器能够发挥最大的作用.这是 GoLang 的最佳卖点之一.此外,Go 速度快,表现力强,干净且高效.这也是 Go 如此吸引开发者学习的原因. PHP 是一种动态类型语言,它使新手更容易编写代码.现在的问题是,PHP 开发人员能否从动态类型语言切换到像 Go 这样的静态类型语言?为了找到答案,让我们对比一下 Go 和 PHP

  • 详解Golang Map中的key为什么是无序的

    目录 一.为什么是无序的? 二.GO 为什么要这么做? 三.遍历是否真的无序的 1.第一次遍历 2.第二次遍历 四.如何才能得到有序的键值对 总结 一.为什么是无序的? 开门见山,先上源码 func mapiterinit(t *maptype, h *hmap, it *hiter) { // decide where to start r := uintptr(fastrand()) if h.B > 31-bucketCntBits { r += uintptr(fastrand()) <

  • 一文详解Golang 定时任务库 gron 设计和原理

    目录 cron 简介 gron 定时参数 源码解析 Cron Entry 按照时间排序 新增定时任务 启动和停止 Schedule 扩展性 经典写法-控制退出 结语 cron 简介 在 Unix-like 操作系统中,有一个大家都很熟悉的 cli 工具,它能够来处理定时任务,周期性任务,这就是: cron. 你只需要简单的语法控制就能实现任意[定时]的语义.用法上可以参考一下这个Crontab Guru Editor,做的非常精巧. 简单说,每一个位都代表了一个时间维度,* 代表全集,所以,上面

  • 一文详解Golang中的切片数据类型

    目录 含义 定义 三个要素 切片与数组的区别 示例代码 切片内存分布 切片定义分类 数组生成切片 示例代码 切片索引 直接声明切片 定义语法 代码示例 使用make定义切片 常用操作 长度计算 容量计算 判断是否为空 切片追加 语法格式 尾部追加 开始位置追加 中间位置追加 复制 引用和复制 切片的删除 删除开头 删除中间 删除结尾 指定位置 排序 迭代器 含义 切片是一个种特殊的数组.是对数组的一个连续片段的引用,所以切片是一个引用类型.切片可以是数组中的一部分,也可以是由起始和终止索引标识的

  • 详解Golang 与python中的字符串反转

    详解Golang 与python中的字符串反转 在go中,需要用rune来处理,因为涉及到中文或者一些字符ASCII编码大于255的. func main() { fmt.Println(reverse("Golang python")) } func reverse(src string) string { dst := []rune(src) len := len(dst) var result []rune result = make([]rune, 0) for i := le

  • 详解Golang 中的并发限制与超时控制

    前言 上回在 用 Go 写一个轻量级的 ssh 批量操作工具里提及过,我们做 Golang 并发的时候要对并发进行限制,对 goroutine 的执行要有超时控制.那会没有细说,这里展开讨论一下. 以下示例代码全部可以直接在 The Go Playground上运行测试: 并发 我们先来跑一个简单的并发看看 package main import ( "fmt" "time" ) func run(task_id, sleeptime int, ch chan st

随机推荐