欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言使用protojson庫(kù)實(shí)現(xiàn)Protocol Buffers與JSON轉(zhuǎn)換

 更新時(shí)間:2023年09月25日 08:44:02   作者:jefffff  
本文主要介紹Google開(kāi)源的工具庫(kù)Protojson庫(kù)如何Protocol Buffers與JSON進(jìn)行轉(zhuǎn)換,以及和標(biāo)準(zhǔn)庫(kù)encoding/json的性能對(duì)比,需要的朋友可以參考下

Protojson 簡(jiǎn)介

Protojson是Google針對(duì)Protocol Buffers數(shù)據(jù)格式的JSON編碼庫(kù),為Go語(yǔ)言開(kāi)發(fā)人員提供了便捷的工具和API,用于Protocol Buffers消息與JSON之間的轉(zhuǎn)換。常用API:

func Format(m proto.Message) string
func Marshal(m proto.Message) ([]byte, error)
func Unmarshal(b []byte, m proto.Message) error
type MarshalOptions
func (o MarshalOptions) Format(m proto.Message) string
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error)
func (o MarshalOptions) MarshalAppend(b []byte, m proto.Message) ([]byte, error)
type UnmarshalOptions
func (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error

接著,我們通過(guò)一些實(shí)踐例子來(lái)演示如何使用。

安裝protoc

  • 設(shè)置Go Env(window os)
# go env -w GOPROXY=https://goproxy.cn
# go env -w GOBIN=%USERPROFILE%\go\bin

其中 USERPROFILE 為默認(rèn)用戶安裝路徑,example: C:\Users\jeffff

  • 下載安裝

下載適合自己os的protoc版本,復(fù)制到GOBIN目錄下,下載鏈接https://github.com/protocolbuffers/protobuf/releases

  • 檢查是否安裝成功
# protoc --version
libprotoc 24.3

安裝protoc-gen-go

這里采用 go install安裝,安裝成功后會(huì)添加到GOBIN目錄下

# go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# protoc-gen-go --version
protoc-gen-go v1.31.0

Example

創(chuàng)建/example/example.proto 創(chuàng)建/exmpale/main.go

syntax = "proto3";
package example.pb;
option go_package = "./;pb";
message User {
  string id = 1;
  string name = 3;
  int32  age = 4;
  string real_name = 5;
  string date = 8;
}

執(zhí)行如下命令,生成/example/example.pb.go文件

#protoc --go_out=. example.proto 

創(chuàng)建main.go,快速實(shí)踐各個(gè)API的功能

package main
import (
    "fmt"
    "github.com/google/uuid"
    "github.com/luckytking/practices/libs/protojson/pb"
    "google.golang.org/protobuf/encoding/protojson"
)
func userInfo() *pb.User {
    return &pb.User{
       Id:       uuid.NewString(),
       Name:     uuid.NewString(),
       Age:      33,
       RealName: uuid.NewString(),
       Date:     "",
       //Date:     time.Now().Format(time.DateTime),
    }
}
func main() {
    info := userInfo()
    fmt.Println("data.Src:", info)
    format := protojson.Format(info)
    fmt.Println("data.Format:", format)
    marshal, err := protojson.Marshal(info)
    if err != nil {
       panic(err)
    }
    fmt.Println("data.Marshal:", string(marshal))
    user1 := &pb.User{}
    err = protojson.Unmarshal(marshal, user1)
    fmt.Println("data.Unmarshal:", user1)
    //marshalOpt :=
    marshal2, err := protojson.MarshalOptions{
       EmitUnpopulated: true,
    }.Marshal(info)
    if err != nil {
       panic(err)
    }
    fmt.Println("data.Marshal2:", string(marshal2))
    user2 := &pb.User{}
    err = protojson.Unmarshal(marshal2, user2)
    fmt.Println("data.Unmarshal2:", user2)
} 

輸出如下:

data.Src: id:"df8bbcca-d8b9-4e41-91ff-6ccf01567d27"  name:"67115015-48bb-4284-b601-e9348a53d40f"  age:33  real_name:"bed916f1-0fb3-413c-9de3-222cbc90c814"
data.Format: {
  "id":  "df8bbcca-d8b9-4e41-91ff-6ccf01567d27",
  "name":  "67115015-48bb-4284-b601-e9348a53d40f",
  "age":  33,
  "realName":  "bed916f1-0fb3-413c-9de3-222cbc90c814"
}
data.Marshal: {"id":"df8bbcca-d8b9-4e41-91ff-6ccf01567d27", "name":"67115015-48bb-4284-b601-e9348a53d40f", "age":33, "realName":"bed916f1-0fb3-413c-9de3-222cbc90c814"}
data.Unmarshal: id:"df8bbcca-d8b9-4e41-91ff-6ccf01567d27"  name:"67115015-48bb-4284-b601-e9348a53d40f"  age:33  real_name:"bed916f1-0fb3-413c-9de3-222cbc90c814"
data.Marshal2: {"id":"df8bbcca-d8b9-4e41-91ff-6ccf01567d27", "name":"67115015-48bb-4284-b601-e9348a53d40f", "age":33, "realName":"bed916f1-0fb3-413c-9de3-222cbc90c814", "date":""}
data.Unmarshal2: id:"df8bbcca-d8b9-4e41-91ff-6ccf01567d27"  name:"67115015-48bb-4284-b601-e9348a53d40f"  age:33  real_name:"bed916f1-0fb3-413c-9de3-222cbc90c814"

上例中:

  • 通過(guò) Marshal 或 MarshalOptions.Marshal 函數(shù)將 protobuf 轉(zhuǎn)換為 JSON 格式.
  • 通過(guò) Unmarshal 或 MarshalOptions.Unmarshal 函數(shù)將JSON 格式的數(shù)據(jù)轉(zhuǎn)換為 protobuf 消息.
  • MarshalOptions 提供了一些自定義選項(xiàng),例如例子中 "EmitUnpopulated: true," 是否輸出未設(shè)置的字段. 這里雖然user.Data=""(默認(rèn)值),但還是輸出了空字符。

更多的option參考

type MarshalOptions struct {
	pragma.NoUnkeyedLiterals
        // Multiline 指定封送拆收器是否應(yīng)以縮進(jìn)形式格式化輸出,并將每個(gè)文本元素放在新行上。// 如果 Indent 是空字符串,則選擇任意縮進(jìn)。
	Multiline bool
        // Indent 指定在多行格式化輸出中使用的縮進(jìn)字符集,
	以便每個(gè)條目前面都有縮進(jìn),并且
	// 以換行符結(jié)尾。如果非空,則 Multiline 被視為 true。
	// 縮進(jìn)只能由空格或制表符組成。
	Indent string
        // AllowPartial 允許對(duì)缺少必填字段的消息進(jìn)行封送
	// 而不返回錯(cuò)誤。如果AllowPartial 為 false(默認(rèn)值),
	// 如果缺少任何必填字段,Marshal 將返回錯(cuò)誤。
	AllowPartial bool
	// UseProtoNames 在 JSON字段名稱中使用 proto 字段名稱而不是小駝峰命名。
	UseProtoNames bool
        // UseEnumNumbers 將枚舉值作為數(shù)字發(fā)出。
	UseEnumNumbers bool
        // EmitUnpopulated 指定是否發(fā)出未填充的字段。//它不會(huì)
	發(fā)出未填充的 oneof 字段或未填充的擴(kuò)展字段。
	// 未填充字段發(fā)出的 JSON 值如下:
	//  ╔═══════╤════════════════════════════╗
	//  ║ JSON  │ Protobuf field             ║
	//  ╠═══════╪════════════════════════════╣
	//  ║ false │ proto3 boolean fields      ║
	//  ║ 0     │ proto3 numeric fields      ║
	//  ║ ""    │ proto3 string/bytes fields ║
	//  ║ null  │ proto2 scalar fields       ║
	//  ║ null  │ message fields             ║
	//  ║ []    │ list fields                ║
	//  ║ {}    │ map fields                 ║
	//  ╚═══════╧════════════════════════════╝
	EmitUnpopulated bool
	// 解析器用于在擴(kuò)展 google.protobuf.Any
	// 消息時(shí)查找類型。如果為零,則默認(rèn)使用 protoregistry.GlobalTypes。
	Resolver interface {
		protoregistry.ExtensionTypeResolver
		protoregistry.MessageTypeResolver
	}
}

性能對(duì)比 protojson VS encoding/json

創(chuàng)建example_test.go

package main
import (
    "encoding/json"
    "google.golang.org/protobuf/encoding/protojson"
    "testing"
)
func BenchmarkProtoJson(b *testing.B) {
    gen := userInfo()
    for i := 0; i < b.N; i++ {
       protojson.Marshal(gen)
    }
}
func BenchmarkStdJson(b *testing.B) {
    gen := userInfo()
    for i := 0; i < b.N; i++ {
       json.Marshal(gen)
    }
} 

結(jié)論如下:

BenchmarkProtoJson
BenchmarkProtoJson-4      230895              4556 ns/op
BenchmarkStdJson
BenchmarkStdJson-4        715443              1732 ns/op

總結(jié)

本文通過(guò)實(shí)踐例子介紹Protojson庫(kù)實(shí)現(xiàn)Protocol Buffers與JSON之間的轉(zhuǎn)換,以及其和標(biāo)準(zhǔn)庫(kù)encoding/json性能對(duì)比。總的來(lái)說(shuō),利用Google Protocol Buffers定制API協(xié)議,和采用Protojson解決傳輸格式轉(zhuǎn)換。在分布式系統(tǒng)無(wú)論是Rpc還是Http的網(wǎng)絡(luò)通信,相信Protojson可以發(fā)揮不錯(cuò)的表現(xiàn)。

以上就是Go語(yǔ)言使用protojson庫(kù)實(shí)現(xiàn)Protocol Buffers與JSON轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于Go Protocol Buffers與JSON轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • go 讀取BMP文件頭二進(jìn)制讀取方式

    go 讀取BMP文件頭二進(jìn)制讀取方式

    這篇文章主要介紹了go 讀取BMP文件頭二進(jìn)制讀取方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go?函數(shù)中獲取調(diào)用者的函數(shù)名和文件名及行號(hào)

    Go?函數(shù)中獲取調(diào)用者的函數(shù)名和文件名及行號(hào)

    這篇文章主要介紹了Go?函數(shù)中獲取調(diào)用者的函數(shù)名和文件名及行號(hào),文章圍主題詳細(xì)內(nèi)容展開(kāi)相關(guān)介紹,感興趣的小伙伴可以參考一下
    2022-05-05
  • Golang?WorkerPool線程池并發(fā)模式示例詳解

    Golang?WorkerPool線程池并發(fā)模式示例詳解

    這篇文章主要為大家介紹了Golang?WorkerPool線程池并發(fā)模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法

    Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Golang教程之不可重入函數(shù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • golang配置管理神器Viper使用教程

    golang配置管理神器Viper使用教程

    這篇文章主要為大家介紹了golang配置管理神器Viper使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實(shí)現(xiàn)示例

    go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了go數(shù)據(jù)結(jié)構(gòu)和算法BitMap原理及實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語(yǔ)言學(xué)習(xí)教程之指針的示例詳解

    Go語(yǔ)言學(xué)習(xí)教程之指針的示例詳解

    這篇文章主要通過(guò)簡(jiǎn)單的練習(xí)來(lái)讓大家對(duì)Go語(yǔ)言中的指針有所了解,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定幫助,需要的可以參考一下
    2022-09-09
  • go語(yǔ)言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)

    go語(yǔ)言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)

    set集合是一種常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),它代表了一個(gè)唯一元素的集合,本文主要介紹了set的基本特性,包括唯一性、無(wú)序性、可變性和集合運(yùn)算,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 利用Go語(yǔ)言實(shí)現(xiàn)Raft日志同步

    利用Go語(yǔ)言實(shí)現(xiàn)Raft日志同步

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語(yǔ)言實(shí)現(xiàn)Raft日志同步,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Go語(yǔ)言有一定的幫助,需要的可以參考一下
    2023-05-05
  • 在Colaboratory上運(yùn)行Go程序的詳細(xì)過(guò)程

    在Colaboratory上運(yùn)行Go程序的詳細(xì)過(guò)程

    這篇文章主要介紹了在Colaboratory上運(yùn)行Go程序,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08

最新評(píng)論