# 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


<<:  Day 30 结束才是开始,参赛反思与改进

>>:  第三十天:UI切版 & 元件-第五部分情境练习(注册表单、产品清单、登入页面)

Day 28 | Unity游戏开发 - 介面设置及场景转换

在上一篇文章提到对话系统的管理,今天我们要来说明主画面设定及场景资料转换。 需要注意的是,介面的素材...

[Day25] Esp32s + IFTTT + LINE

1.前言 前两篇使用到日常生活中使用率最高的通讯软件LINE Notify功能,不知道各位小夥伴是否...

实战操作 - 鸿海 2317

鸿海是我个人主要标的之一,趁星期五(10/1)指数大跌,趁机再次加码。 主要大量进场时间点是在去年底...

DAY 1 系列文章启文

近年来 ROS (Robot Operating System,机器人作业系统) 目前已成熟应用於智...

Day 14: Structural patterns - Decorator

目的 使用包覆(Wrapper)的方式,可以动态地给物件增添新的功能,或是重新定义既有的功能,达到扩...