iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

0
Software Development

Go繁不及備載系列 第 31

# Day31 Golang Protobuf 介紹與使用

Day31 Golang Protobuf 介紹與使用

Protobuf 介紹

Protobuf 是由 Google 開發的一種可跨平台、跨語言的數據交換格式,
是一種將結構化資料 序列化(變成二進制)的方法。資料要比json格式更小更輕便。

Protobuf是Protocol Buffers的簡寫,翻成中文為協議緩衝區
這名詞很抽象也很抽痛。

Protocol: 協定、協議

你我倆約定、協商好、談妥的東西,或者叫做條款,

ex: 你給我1000元新台幣,我去幫你到店裡買一包七星菸抽其中一根給你。

可以是A、B服務之間傳遞的格式、交換、處理的事情。

Buffer: 一塊(特定大小的)空間。

Protocol Buffers: 你我講好的協議所用到的某一塊空間

在資訊世界裡,資料放在空間中就必需要有格式,
首先來看看這個格式是什麼。


Protobuf 的格式

Protobuf的格式為proto,目前有 proto2proto3 兩種版本,
兩者有一些差異,主要為proto3閹割掉了一些較不嚴謹的功能。
這邊用法上會以proto3為主。

首先創建一個檔案為 school.proto

syntax = "proto3";
option go_package = ".;school";

message Teacher{
  string name = 1;
  int32 age = 2;
}

數字代表的意義

上方的數字name = 1age = 2的數字1與2,不是賦值的意思,
不是說名字=1、年齡=2,
而是 編號、唯一識別碼,好讓程式識別這個變數,因為到時大家都被壓縮成二進制 認不出誰是誰,有編號要認人比較方便。
在同一個message裡面識別碼不可重複,但不同message之間重複就沒關係了。
這個識別碼編號方式也沒什麼硬性規定,通常會由上往下從1、2、3... 開始依序給。
值得一提的是,編號1~15識別碼的區域會使用1 byte來作編碼,
位於16~2047 之間的識別碼區域則會用到2 bytes來作編碼。
所以可以將較常使用到的欄位盡量都放在1~15的位置,進而減少資料的傳輸量。

【Goland IDE設定】

下載能支援proto語法偵測的套件,讓proto語法能夠高亮。

Setting -> Plugins -> search 搜尋"protobuf" -> search in Marketplace 安裝 Protocol Buffer Editor 接著 Enable、Apply
.proto file

這樣一來就能支援偵測.proto檔案的語法了~

安裝方法

我們透過 proto語法介面描述語言(IDL) 來自己定義自己想要的結構,
接著使用Protoc編譯器(Protocol-Buffer-Compiler)來將語法結構變成格式。

要在golang上使用proto,首先要載 Protoc編譯器
以及為了能順利轉出golang的結構物件,需下載支援 產生go語言的插件protoc-gen-go

安裝protoc

首先 到這 點擊Download 下載符合自己電腦(Windows、MacOS、Linux)的編譯器。

解壓縮後按照readme的步驟安裝,
bin資料夾底下的東西放到PATH中,
include資料夾底下放的是可選擇安裝的proto插件,建議也一併放入到位。

MacOS 可以放在:

/usr/local/bin        放bin資料夾底下的東西
/usr/local/include    放include資料夾底下的東西

Windows 可以放:

C:\Users\USER\go\bin         放bin資料夾底下的東西  
C:\Users\USER\go\include     放include資料夾底下的東西  

或者

C:\Go\bin        放bin資料夾底下的東西  
C:\Go\include    放include資料夾底下的東西

也可以直接放入

C:\WINDOWS\System32

安裝protoc-gen-go plugin

$ go get -u github.com/golang/protobuf/protoc-gen-go

產生結構物件 - pb.go檔案

$ protoc --go_out=:. school.proto

下完這行指令就能看到資料夾底下有school.pb.go的程式出現了!

在程式中使用物件

有了school.pb.go,等於是電腦自動幫你完成這物件的結構哩。

package main

import (
	"fmt"
	pb "...省略/proto"
)

func main() {
	teacher := pb.Teacher{Name: "Jack", Age: 32}
	fmt.Printf("%+v\n", teacher)

	tName := teacher.GetName()
	tAge := teacher.GetAge()
	fmt.Println(tName, tAge)
}

不過要小注意的是,這邊的Teacher物件中的Age屬性,格式是int32

可以進去school.pb.go看這支程式裡面所寫的所有用法、func


上一篇
# Day30 Golang 鍵值資料庫 Redis 實作抽獎小遊戲
下一篇
# Day32 寫在Go繁之後
系列文
Go繁不及備載32

尚未有邦友留言

立即登入留言