Windows protoBuf 安装+学习

文章目录

  • 一、protoBuf是什么?
  • 二、protoBuf优缺点
    • 优点
    • 缺点
  • 三、protoBuf组件安装
    • 1. protoc下载
    • 2. protoc-gen-go下载
    • 四、protoc命令
    • 五、protoBuf语法
    • 1. 例子
    • 2. message的格式说明
    • 3. message常见的数据类型与go中类型对比
    • 4. protobuf高级用法


一、protoBuf是什么?

  1. protobuf是类似与json一样的数据描述语言(数据格式)
  2. protobuf非常适合于RPC数据交换格式
    protoBuf是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

二、protoBuf优缺点

优点

  1. 序列化后体积相比Json和XML很小,适合网络传输
  2. 支持跨平台多语言
  3. 消息格式升级和兼容性还不错
  4. 序列化反序列化速度很快,快于Json的处理速度

缺点

  1. 应用不够广(相比xml和json)
  2. 二进制格式导致可读性差(因为是二进制格式,所以安全性较好)
  3. 缺乏自描述
xml json protoBuf
体积 很小
传输效率 相对json慢 很快
简单性 结构复杂 结构简单 相对简单
通用性 没有json普遍 普遍 不普遍
可读性 凑合 差,二进制文件

三、protoBuf组件安装

1. protoc下载

下载链接:https://github.com/protocolbuffers/protobuf/releases
Windows protoBuf 安装+学习_第1张图片
在任意地方新建一个protobuf文件夹,将下载好的压缩包解压到protobuf文件夹中,本文在E盘下新建protobuf文件夹。解压后,进入其bin目录,会看见protoc.exe文件
Windows protoBuf 安装+学习_第2张图片


配置环境变量
方法一:直接将protoc.exe复制到GOPATH/bin
方法二:配置环境变量:
环境变量-系统变量-Path-编辑-新建-proto.exe所在的路径,本文即:E:\protobuf\bin
为了统一方便管理,建议使用方法一。

验证:打开cmd,输入protoc --version


2. protoc-gen-go下载

下载:go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
最后在GOPATH/bin中看到protoc-gen-go.exe文件说明安装成功。


四、protoc命令

protoc xxx.proto --go_out=.
或者
protoc --go_out=. xxx.proto
或者
protoc --go_out=. *.proto

五、protoBuf语法

1. 例子

参考文档(需):https://developers.google.com/protocol-buffers/docs/proto3

syntax = "proto3"; 						//指定版本信息,不指定会报错
package pb;						//后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
	//    名字
    string name = 1;
	//    年龄
    int32  age = 2 ;
}

enum test{
	int32 age = 0;
}
  • protobuf消息的定义(或者称为描述)通常都写在一个以 .proto 结尾的文件中。
  • 该文件的第一行指定正在使用proto3语法:如果不这样做,协议缓冲区编译器将假定正在使用proto2。这也必须是文件的第一个非空的非注释行。
  • 第二行package指明当前是pb包(生成go文件之后和Go的包名保持一致)
  • 最后message关键字定义一个Person消息体,类似于go语言中的结构体,是包含一系列类型数据的集合。许多标准的简单数据类型都可以作为字段类型,包括boolint32floatdouble,和string。也可以使用其他message类型作为字段类型。
  • 在message中有一个字符串类型的value成员,该成员编码时用1代替名字。我们知道,在json中是通过成员的名字来绑定对应的数据,但是Protobuf编码却是通过成员的唯一编号来绑定对应的数据,因此Protobuf编码后数据的体积会比较小,能够快速传输,缺点是不利于阅读。

2. message的格式说明

消息由至少一个字段组合而成,类似于Go语言中的结构体,每个字段都有一定的格式:

//注释格式 注释尽量也写在内容上方
(字段修饰符)数据类型 字段名称 = 唯一的编号标签值;

3. message常见的数据类型与go中类型对比

.proto类型 Go类型 介绍
double float64 64位浮点数
float float32 32位浮点数
int32 int32 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint32。
int64 int64 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint64。
uint32 uint32 使用可变长度编码。
uint64 uint64 使用可变长度编码。
sint32 int32 使用可变长度编码。符号整型值。这些比常规int32s编码负数更有效。
sint64 int64 使用可变长度编码。符号整型值。这些比常规int64s编码负数更有效。
fixed32 uint32 总是四字节。如果值通常大于228,则比uint 32更有效
fixed64 uint64 总是八字节。如果值通常大于256,则比uint64更有效
sfixed32 int32 总是四字节。
sfixed64 int64 总是八字节。
bool bool 布尔类型
string string 字符串必须始终包含UTF - 8编码或7位ASCII文本
bytes []byte 可以包含任意字节序列

4. protobuf高级用法

protobuf除了上面的简单类型还有一些复杂的用法,如下:

message嵌套

messsage除了能放简单数据类型外,还能存放另外的message类型,如下:

syntax = "proto3"; 				//指定版本信息,不指定会报错,默认proto2
package pb;						//后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
	//    名字
    string name = 1;   //编号可以不从1开始,但是不能重复。也不能使用19000 ~ 19999
	//    年龄
    int32  age = 2 ;
    //定义一个message
    message PhoneNumber {
    string number = 1;
    int64 type = 2;
	}
	PhoneNumber phone = 3;
}

repeated关键字

repeadted关键字类似与go中的切片,编译之后对应的也是go的切片,用法如下:

syntax = "proto3"; 						//指定版本信息,不指定会报错
package pb;						//后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
	//    名字
    string name = 1;
	//    年龄
    int32  age = 2 ;
    //定义一个message
    message PhoneNumber {
    string number = 1;
    int64 type = 2;
	}
	
	repeated PhoneNumber phone = 3;
}

默认值

解析数据时,如果编码的消息不包含特定的单数元素,则解析对象对象中的相应字段将设置为该字段的默认值。不同类型的默认值不同,具体如下:

  • 对于字符串,默认值为空字符串。
  • 对于字节,默认值为空字节。
  • 对于bools,默认值为false。
  • 对于数字类型,默认值为零。
  • 对于枚举,默认值是第一个定义的枚举值,该必须为0。
  • repeated字段默认值是空列表
  • message字段的默认值为空对象

enum关键字

在定义消息类型时,可能会希望其中一个字段有一个预定义的值列表。比如说,电话号码字段有个类型,这个类型可以是,home,work,mobile。我们可以通过enum在消息定义中添加每个可能值的常量来非常简单的执行此操作。实例如下:

syntax = "proto3"; 						//指定版本信息,不指定会报错
package pb;						//后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
	//    名字
    string name = 1;
	//    年龄
    int32  age = 2 ;
    //定义一个message
    message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
	}
	
	repeated PhoneNumber phone = 3;
}

//enum为关键字,作用为定义一种枚举类型
enum PhoneType {
	MOBILE = 0;  //枚举值必须从0开始
    HOME = 1;
    WORK = 2;
}

如上,enum的第一个常量映射为0,每个枚举定义必须包含一个映射到零的常量作为其第一个元素。这是因为:

  • 必须有一个零值,以便我们可以使用0作为数字默认值。
  • 零值必须是第一个元素,以便与proto2语义兼容,其中第一个枚举值始终是默认值。

enum还可以为不同的枚举常量指定相同的值来定义别名。如果想要使用这个功能必须讲allow_alias选项设置为true,负责编译器将报错。示例如下:

syntax = "proto3"; 						//指定版本信息,不指定会报错
package pb;						//后期生成go文件的包名
//message为关键字,作用为定义一种消息类型
message Person{
    //    名字
    string name = 1;
    //    年龄
    int32  age = 2 ;
    //定义一个message
    message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
    }

    repeated PhoneNumber phone = 3;
}

//enum为关键字,作用为定义一种枚举类型
enum PhoneType {
	//如果不设置将报错
    option allow_alias = true;
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
    Personal = 2;
}

oneof关键字

如果有一个包含许多字段的消息,并且最多只能同时设置其中的一个字段(联合体),则可以使用oneof功能,示例如下:

message Person{
    //    名字
    string name = 1;
    //    年龄
    int32  age = 2 ;
    //定义一个message
    message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
    }

    repeated PhoneNumber phone = 3;
    oneof data{
        string school = 5;  //编号不能重复,根据习惯顺次往下编
        int32 score = 6;
    }
}

你可能感兴趣的:(微服务,golang)