golang使用protobuf

2,461 阅读1分钟

windows 环境

  • 下载protoc 连接, 下载的是 protoc-3.12.4-win64.zip压缩包,解压到磁盘
  • 配置环境变量, 在path中配置protoc.exe所在的地址:D:\dev\protoc-3.12.4-win64\bin
>> protoc --version
libprotoc 3.12.4

第一种,protobuf模块和其他插件

# protoc-gen-go是用来将protobuf的的代码转换成go语言代码的一个插件
>> go get -u github.com/golang/protobuf/protoc-gen-go
# proto是protobuf在golang中的接口模块
>> go get -u github.com/golang/protobuf/proto
  • 编译proto文件,生成go文件
 protoc --go_out=. *.proto

第二种,gogoprotobuf模块和其他插件

  • gogoprotobuf有两个插件可以使用
    protoc-gen-gogo:和protoc-gen-go生成的文件差不多,性能也几乎一样(稍微快一点点)
    protoc-gen-gofast:生成的文件更复杂,性能也更高(快5-7倍)

  • 安装gogoprotobuf库文件

go get github.com/gogo/protobuf/proto
go get github.com/gogo/protobuf/gogoproto  //这个不装也没关系
  • 编译proto文件,生成go文件
//gogo
protoc --gogo_out=. *.proto

//gofast
protoc --gofast_out=. *.proto

性能测试

//goprotobuf
"编码":447ns/op
"解码":422ns/op

//gogoprotobuf-go
"编码":433ns/op
"解码":427ns/op

//gogoprotobuf-fast
"编码":112ns/op
"解码":112ns/op

测试

person.proto

syntax = "proto3";
package yida;

message person {    //  aa 会生成 Aa 命名的结构体
  int32 id = 1;
  string name = 2;
}

message all_person {    //  aa_bb 会生成 AaBb 的驼峰命名的结构体
  repeated person Per = 1;
}

main.go

package main

import (
	"demo/yida"
	"google.golang.org/protobuf/proto"
	"log"
)

func main() {
	// 为 AllPerson 填充数据
	p1 := yida.Person{
		Id:*proto.Int32(1),
		Name:*proto.String("xieyanke"),
	}

	p2 := yida.Person{
		Id:2,
		Name:"gopher",
	}

	all_p := yida.AllPerson{
		Per:[]*yida.Person{&p1, &p2},
	}

	// 对数据进行序列化
	data, err := proto.Marshal(&all_p)
	if err != nil {
		log.Fatalln("Mashal data error:", err)
	}

	// 对已经序列化的数据进行反序列化
	var target yida.AllPerson
	err = proto.Unmarshal(data, &target)
	if err != nil{
		log.Fatalln("UnMashal data error:", err)
	}

	println(target.Per[0].Name) // 打印第一个 person Name 的值进行反序列化验证*/
}

参考: golang使用protobuf Golang 序列化之 ProtoBuf