理解Golang組件protobuf

来源:https://www.cnblogs.com/enochzzg/archive/2020/03/26/12577966.html

什麼是protobuf protocol buffers 是一種語言無關、平臺無關、可擴展的序列化結構數據的方法,它可用於(數據)通信協議、數據存儲等。是一種靈活,高效,自動化機制的結構數據序列化方法-可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單。 p ...


什麼是protobuf

protocol buffers 是一種語言無關、平臺無關、可擴展的序列化結構數據的方法,它可用於(數據)通信協議、數據存儲等。是一種靈活,高效,自動化機制的結構數據序列化方法-可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單。

protobuf與json區別

JSON與Protobuf都可以用來信息交換,JSON是一種簡單的消息格式,以文本方式傳輸,而Protobuf是以二進位方式進行傳輸,相較於JSON消息體積會有明顯的縮小,所以傳輸速度也比JSON快。除此之外,Protobuf不僅僅是一種用於交換的消息格式,還是用於定義交換消息的規則和工具,目前基本支持所有的主流語言。

使用

先通過命令行進行安裝

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

再創建一個名為test.proto的文件,鍵入以下內容

syntax = "proto3";
package main;

message Test {
    string label = 1;
    int32 type = 2;
    repeated int64 reps = 3;
}

我們以proto3為例,創建一個叫Test的message,設置三個屬性,label、type和int64,repeated對應生成的Go語言變數類型為切片。下麵在命令行執行protoc來生成Go文件。

protoc --go_out=./ test.proto

可以看到在根目錄中生成了一個名為test.pb.go的文件

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test.proto

package main

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type Test struct {
	Label                string   `protobuf:"bytes,1,opt,name=label,proto3" json:"label,omitempty"`
	Type                 int32    `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
	Reps                 []int64  `protobuf:"varint,3,rep,packed,name=reps,proto3" json:"reps,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Test) Reset()         { *m = Test{} }
func (m *Test) String() string { return proto.CompactTextString(m) }
func (*Test) ProtoMessage()    {}
func (*Test) Descriptor() ([]byte, []int) {
	return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
}

func (m *Test) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Test.Unmarshal(m, b)
}
func (m *Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Test.Marshal(b, m, deterministic)
}
func (m *Test) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Test.Merge(m, src)
}
func (m *Test) XXX_Size() int {
	return xxx_messageInfo_Test.Size(m)
}
func (m *Test) XXX_DiscardUnknown() {
	xxx_messageInfo_Test.DiscardUnknown(m)
}

var xxx_messageInfo_Test proto.InternalMessageInfo

func (m *Test) GetLabel() string {
	if m != nil {
		return m.Label
	}
	return ""
}

func (m *Test) GetType() int32 {
	if m != nil {
		return m.Type
	}
	return 0
}

func (m *Test) GetReps() []int64 {
	if m != nil {
		return m.Reps
	}
	return nil
}

func init() {
	proto.RegisterType((*Test)(nil), "main.Test")
}

func init() {
	proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e)
}

var fileDescriptor_c161fcfdc0c3ff1e = []byte{
	// 104 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x49, 0x2d, 0x2e,
	0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0x72, 0xe1, 0x62,
	0x09, 0x49, 0x2d, 0x2e, 0x11, 0x12, 0xe1, 0x62, 0xcd, 0x49, 0x4c, 0x4a, 0xcd, 0x91, 0x60, 0x54,
	0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x84, 0x84, 0xb8, 0x58, 0x4a, 0x2a, 0x0b, 0x52, 0x25, 0x98,
	0x14, 0x18, 0x35, 0x58, 0x83, 0xc0, 0x6c, 0x90, 0x58, 0x51, 0x6a, 0x41, 0xb1, 0x04, 0xb3, 0x02,
	0xb3, 0x06, 0x73, 0x10, 0x98, 0x9d, 0xc4, 0x06, 0x36, 0xd2, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff,
	0x7b, 0xa2, 0xc6, 0x01, 0x60, 0x00, 0x00, 0x00,
}

我們在main文件中進行序列化測試

package main

import (
	"fmt"

	"github.com/golang/protobuf/proto"
)

func main() {
	test := &Test{
		Label: "a",
		Type:  32,
		Reps:  []int64{10, 11},
	}
	resp, err := proto.Marshal(test)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(resp)
}

protobuf生成了一個名為Test的結構體,其中有三個成員屬性,正好與test.proto文件對應,執行poroto.Marshal方法可以對結構體進行序列化,後續就可以藉助RPC或HTTP的載體進行傳輸。

Golang組件示例代碼倉庫,歡迎star

https://github.com/EnochZg/golang-examples


您的分享是我們最大的動力!

更多相關文章
  • 初始化 變數: c:int cwls = 10; c++: int wrens(432); c++11: int emus{7}; int rheas={12}; 括弧中不包含任何東西,變數初始化為 0 ; 適用於任何類型,等號可有可無; 結構體: C: inflatable guest= { "G ...
  • 枚舉 enum:創建符號常量的方式 enum spectrum { red, orange, yellow, green, blue, violet, indigo, ultraviolet }; spectrum 被稱為枚舉,red 等作為符號常量,這些符號常量叫做枚舉量。 預設將整數值賦給枚舉量 ...
  • 字元串輸入 面向單詞 cin : 使用空白(空格、製表符和換行符)來確定字元串的結束位置。 自動添加空字元。 面向行 getline(m,n) m 存儲輸入行的數組名稱,n 為讀取字元數。 最多讀取 n-1 個字元,自動添加空字元。 換行符確定輸入結尾,停止讀取。 不保存換行符,用空字元代替換行符。 ...
  • 在前一篇文章中,我們已經介紹了 Spring IOC 的相關知識,今天將為個位介紹 Spring 中 Bean 的相關知識。關註我的公眾號「Java面典」,每天 10:24 和你一起瞭解更多 Java 相關知識點。 Bean 的生命周期 Spring 生命周期有四個階段,分別是: 1. 實例化 In ...
  • 什麼是SSRF 一個對外的Web介面,改介面能讓用戶控制curl命令,去訪問別的web服務。 簡圖如下 想象一下當用戶請求的 改成 ,是不是覺得原本不可能訪問到內網的主機,現在就很容易就能做到了。 原理 PHP代碼演示: 1.查看代碼的時候檢查是否使用curl_setopt( )函數; 2.在看傳入 ...
  • title: 博客歸納 blog: "CSDN" data: "Java學習路線及視頻" 2019 12/31 "時間管理" 2020 1/22 "Git是什麼?" 1/23 "Git安裝 Windows" 3/24 "3000字編程入門 附帶Java學習路線及視頻" 3/25 "淺談Java語言環 ...
  • @ + function表示忽略警告。 eval() 是可以執行php代碼 system() 是可以執行系統命令 ...
  • 原創聲明 本文首發於微信公眾號【程式員黃小斜】 本文作者:黃小斜 轉載請務必在文章開頭註明出處和作者。 本文思維導圖 什麼是Spring,為什麼你要學習spring? 你第一次接觸spring框架是在什麼時候?相信很多人和我一樣,第一次瞭解spring都不是做項目的時候用到,而是在網上看到或者是聽到 ...
一周排行
  • 在上篇文章中我們已經知道了多線程是什麼了,那麼它到底可以幹嘛呢?這裡特別聲明一個前面的委托沒看的同學可以到上上上篇博文查看,因為多線程要經常使用到委托。源碼 一、非同步、同步 1.同步(在計算的理解總是要你措不及防,同步當線程做完一件事情之後,才會執行後續動作),同步方法慢,只有一個線程執行,非同步方法 ...
  • 本文主要是講解stopwatch對程式運行時間的準確測量 僅僅介紹裡面的StartNew()方法,Restart()方法和ElapsedMilliseconds { get;}屬性 public void StartNew():作用是對新的 System.Diagnostics.Stopwatch ...
  • 一、引言 RabbitMQ是Rabbit Message Queue的簡寫,但不能僅僅理解其為消息隊列,消息代理更合適。RabbitMQ是一個由 Erlang 語言開發的AMQP(高級消息隊列協議)的開源實現,其內部結構如下: RabbitMQ作為一個消息代理,主要和消息打交道,負責接收並轉發消息。 ...
  • TerminalMACS(Terminal Manager And Check System) 遠程終端管理和檢測系統 本文同步更新地址:https://dotnet9.com/11429.html 一、本系統可監控多種終端資源: 移動端 Android iOS PC端 Windows Linux ...
  • 首先,好消息是Goole將於2020年2月份發佈Chrome 80版本。本次發佈將推進Google的“漸進改良Cookie”策略,打造一個更為安全和保障用戶隱私的網路環境。 壞消息是,本次更新可能導致瀏覽器無法向服務端發送Cookie。如果你有多個不同功能變數名稱的應用,部分用戶很有可能出現會話時常被打斷的 ...
  • 在偶然一次調試某程式時,遇到提示: 無法載入程式集*****.XmlSerializers.dll,文件找不到(Could not load file or assembly ****.XmlSerializers.dll , FileNotFoundException...)。於是嘗試在項目屬性中 ...
  • 在上一篇abp(net core)+easyui+efcore實現倉儲管理系統——入庫管理之五(四十一) 文章中實現了入庫管理的列表頁面,並實現了控制器的代碼。在今天我們學習如何在前端實現新增入庫單信息界面。 ...
  • 面向對象 面向對象是一個抽象的概念,其本質就是對事物以抽象的方式建立對應的模型。 簡單來講,比如我有一隻鋼筆,那麼我就可以通過分析,可以得到 這隻鋼筆的材第是塑料,品牌是個雜牌 ,裡面裝的墨是黑色的,可以用。這時候就能建立一個鋼筆的模型,它在這裡應該有這些屬性: 圖是一個不正確的UML類圖,但是可以 ...
  • 在ASP.NET MVC中有四種過濾器類型 Action 1、在ASP.NET MVC項目中,新建文件夾Filter,然後新建類MyCustormFilter,繼承自ActionFilterAttribute類,我們來看下ActionFilterAttribute類有如下四個方法,從命名我應該就可以 ...
  • 你需要瞭解的 HTTP Status Code Intro 現在前後端分離的開發模式越來越流行,後端負責開發對應的 API,前端只需要 關註前端頁面的數據展示和前端邏輯即可。 對於前後端分離這種開發模式,我個人還是比較喜歡的,因為這樣可以讓更專業的人做更專業的事情,後端專註於做 API 的開發設計, ...
x