欢迎程序员们!在这个教程里面,咱们将学习如何使用protocol Buffers数据格式在你的go应用里面. 咱们将详细讲述这种数据格式, 以及为何这种数据格式优于传统的数据格式例如xml甚至JSON. 在咱们写更多复杂的例子以前,咱们将从一个简单的例子开始编写运行.git
在这章教的最后,你会对protoco Buffe有一个基础的了解,而且你将能够顺利的写出你本身更好的系统.程序员
https://www.youtube.com/embed/NoDRq6Twkts?ecver=2
Protocol buffers是基础的数据格式, 和JSON,XML很是的类似, 都是用于存储结构化的数据,都支持不少不一样的语言使用并进行序列化和反序列化.github
这种数据格式最大的优势就是它相比xml甚至JSON的大小要小不少. 这种格式是由Google开发的.Goggole是很是有名的公司,它的规模如此之大,他们作的每一件事情都产生深渊的影响.golang
假设有一我的, 咱们想用三个独立的数据表示他:数组
<person> <name>Elliot</name> <age>24</age> </person>
咱们可使用更小的数据格式JSON表示他:数据结构
{ "name": "Elliot", "age": 24 }
若是咱们使用protocol buffer数据格式表示以下:学习
[10 6 69 108 108 105 111 116 16 24]
若是你仔细观察上面一行的编码输出, 你能够看到从数组下标为二的位置开始,ellio
就拼出来了.e
=69,l
=108等. 后面的字节表示我如今24岁了.this
可是这个编码内容比咱们看到的要多的多. 我仍然在尝试研究更多信息.若是你愿意,我建议能够查看更多Google关于protocol Buffer编码的文档: Protocol Buffer Encodinggoogle
虽然JSON和Protocol Buffer的大小几乎相同.可是随着数据增大大于"入门"例子的数据,Json和protocol buffer使用的空间差距就变大了.编码
& go get github.com/golang/protobuf $ go get github.com/golang/protobuf/proto
上面下载一些必须的包,用于运行简单的例子.
($) export PATH=$PATH:$GOPATH/bin
进行上面的设置以后,你就能够在终端使用protoc
这个命令了. 下面咱们就能够定义protobuf的格式了,在这个例子里,咱们将尝试使用相同的person
这个对象,咱们用这个突出不一样数据格式之间的区别.
首先咱们要指出要使用的协议类型, 在这个例子里面咱们使用proto3
. 而后我把它做为main
包的一部分.
最后咱们定义咱们想要的数据结构. 这个包含了Person
的消息结构,其中包含了name
和 age
两个字段.
syntax="proto3"; package main; message Person { string name = 1; int32 age = 2; }
而后咱们使用protoc
命令编译这个文件.
And we can then compile this using the protoc binary:
最终咱们准备好写咱们GO代码的全部东西. 咱们从定义一个Person
开始,并将这个对象编译成protobuf
对象.
为了了解它是如何存储的,咱们使用fmt.Println(data)
打印存储protobuf
对象的编码数据.
package main import ( "fmt" "log" "github.com/golang/protobuf/proto" ) func main() { elliot := &Person{ Name: "Elliot", Age: 24, } data, err := proto.Marshal(elliot) if err != nil { log.Fatal("marshaling error: ", err) } // printing out our raw protobuf object fmt.Println(data) // let's go the other way and unmarshal // our byte array into an object we can modify // and use newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // print out our `newElliot` object // for good measure fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.GetName()) }
在运行以前,咱们须要将`test.pb.go'编译经过以保证正常工做:
➜ src go run main.go test.pb.go [10 6 69 108 108 105 111 116 16 24] name:"Elliot" age:24
好了,咱们实现了一个很是简单的例子并运行了它,可是在实际中,咱们常常遇到在messag的格式里面有嵌套的字段,而且可能会修改一些它们的值.
如今咱们开始看看如何使用嵌套字段. 咱们继续使用 Person
这个消息格式,咱们将添加一个社交媒体的追随者的字段.
咱们用标准的字段以及自定义的SocialFollowers
消息字段组成Person这个消息格式,像下面这样:
syntax="proto3"; package main; message SocialFollowers { int32 youtube = 1; int32 twitter = 2; } message Person { string name = 1; int32 age = 2; SocialFollowers socialFollowers = 3; }
再一次,咱们使用protoc
这个命令生成咱们想要的东西.
($) protoc --go_out=. *.proto
而后咱们再回到咱们的Go程序,咱们能够用SocialFollowers
补充咱们的elliot
对象:
package main import ( "fmt" "log" "github.com/golang/protobuf/proto" ) func main() { elliot := Person{ Name: "Elliot", Age: 24, SocialFollowers: &SocialFollowers{ Youtube: 2500, Twitter: 1400, }, } data, err := proto.Marshal(&elliot) if err != nil { log.Fatal("marshaling error: ", err) } // let's go the other way and unmarshal // our protocol buffer into an object we can modify // and use newElliot := &Person{} err = proto.Unmarshal(data, newElliot) if err != nil { log.Fatal("unmarshaling error: ", err) } // print out our `newElliot` object // for good measure fmt.Println(newElliot.GetName()) fmt.Println(newElliot.GetAge()) fmt.Println(newElliot.SocialFollowers.GetTwitter()) fmt.Println(newElliot.SocialFollowers.GetYoutube()) }
咱们来最后一次运行它,咱们看到了全部咱们但愿输出的内容:
➜ src go run main.go test.pb.go Elliot 24 1400 2500
在这个教程里面, 咱们了解了如何基于Go应用程序使用protocol buffer创建数据结构并运行,
但愿这个教程对您有用。
via: https://tutorialedge.net/golang/go-protocol-buffer-tutorial/
做者:tutorialedge.net 译者:amei 校对:校对者ID