最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言使用protojson庫實現(xiàn)Protocol Buffers與JSON轉換

 更新時間:2023年09月25日 08:44:02   作者:jefffff  
本文主要介紹Google開源的工具庫Protojson庫如何Protocol Buffers與JSON進行轉換,以及和標準庫encoding/json的性能對比,需要的朋友可以參考下

Protojson 簡介

Protojson是Google針對Protocol Buffers數(shù)據(jù)格式的JSON編碼庫,為Go語言開發(fā)人員提供了便捷的工具和API,用于Protocol Buffers消息與JSON之間的轉換。常用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

接著,我們通過一些實踐例子來演示如何使用。

安裝protoc

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

其中 USERPROFILE 為默認用戶安裝路徑,example: C:\Users\jeffff

  • 下載安裝

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

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

安裝protoc-gen-go

這里采用 go install安裝,安裝成功后會添加到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,快速實踐各個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"

上例中:

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

更多的option參考

type MarshalOptions struct {
	pragma.NoUnkeyedLiterals
        // Multiline 指定封送拆收器是否應以縮進形式格式化輸出,并將每個文本元素放在新行上。// 如果 Indent 是空字符串,則選擇任意縮進。
	Multiline bool
        // Indent 指定在多行格式化輸出中使用的縮進字符集,
	以便每個條目前面都有縮進,并且
	// 以換行符結尾。如果非空,則 Multiline 被視為 true。
	// 縮進只能由空格或制表符組成。
	Indent string
        // AllowPartial 允許對缺少必填字段的消息進行封送
	// 而不返回錯誤。如果AllowPartial 為 false(默認值),
	// 如果缺少任何必填字段,Marshal 將返回錯誤。
	AllowPartial bool
	// UseProtoNames 在 JSON字段名稱中使用 proto 字段名稱而不是小駝峰命名。
	UseProtoNames bool
        // UseEnumNumbers 將枚舉值作為數(shù)字發(fā)出。
	UseEnumNumbers bool
        // EmitUnpopulated 指定是否發(fā)出未填充的字段。//它不會
	發(fā)出未填充的 oneof 字段或未填充的擴展字段。
	// 未填充字段發(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
	// 解析器用于在擴展 google.protobuf.Any
	// 消息時查找類型。如果為零,則默認使用 protoregistry.GlobalTypes。
	Resolver interface {
		protoregistry.ExtensionTypeResolver
		protoregistry.MessageTypeResolver
	}
}

性能對比 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)
    }
} 

結論如下:

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

總結

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

以上就是Go語言使用protojson庫實現(xiàn)Protocol Buffers與JSON轉換的詳細內容,更多關于Go Protocol Buffers與JSON轉換的資料請關注腳本之家其它相關文章!

相關文章

  • Go?不支持?[]T轉換為[]interface類型詳解

    Go?不支持?[]T轉換為[]interface類型詳解

    這篇文章主要為大家介紹了Go不支持[]T轉換為[]interface類型詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 數(shù)據(jù)競爭和內存重分配Golang slice并發(fā)不安全問題解決

    數(shù)據(jù)競爭和內存重分配Golang slice并發(fā)不安全問題解決

    這篇文章主要為大家介紹了數(shù)據(jù)競爭和內存重分配Golang slice并發(fā)不安全問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • golang版本升級的簡單實現(xiàn)步驟

    golang版本升級的簡單實現(xiàn)步驟

    個人感覺Go在眾多高級語言中,是在各方面都比較高效的,下面這篇文章主要給大家介紹了關于golang版本升級的簡單實現(xiàn)步驟,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • Golang中Gin數(shù)據(jù)庫表名前綴的三種方法

    Golang中Gin數(shù)據(jù)庫表名前綴的三種方法

    本文主要介紹了Golang中Gin數(shù)據(jù)庫表名前綴的三種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • Go方法接收者值接收者與指針接收者詳解

    Go方法接收者值接收者與指針接收者詳解

    這篇文章主要為大家介紹了Go方法接收者值接收者與指針接收者詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Go-ethereum?解析ethersjs中產(chǎn)生的簽名信息思路詳解

    Go-ethereum?解析ethersjs中產(chǎn)生的簽名信息思路詳解

    這篇文章主要介紹了Go-ethereum?解析ethersjs中產(chǎn)生的簽名信息,我們解析簽名的需要知道,簽名的消息,簽名,和公鑰,按照這個思路,我們可以通過ethers實現(xiàn)消息的簽名,也可以通過go-ethereum實現(xiàn),需要的朋友可以參考下
    2022-08-08
  • golang中slice擴容的具體實現(xiàn)

    golang中slice擴容的具體實現(xiàn)

    Go 語言中的切片擴容機制是 Go 運行時的一個關鍵部分,它確保切片在動態(tài)增加元素時能夠高效地管理內存,本文主要介紹了golang中slice擴容的具體實現(xiàn),感興趣的可以了解一下
    2025-05-05
  • golang實現(xiàn)協(xié)程池的方法示例

    golang實現(xiàn)協(xié)程池的方法示例

    本文主要介紹了golang實現(xiàn)協(xié)程池的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-02-02
  • go如何刪除字符串中的部分字符

    go如何刪除字符串中的部分字符

    這篇文章主要介紹了go刪除字符串中的部分字符操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言中的IO操作及Flag包的用法

    Go語言中的IO操作及Flag包的用法

    這篇文章介紹了Go語言中的IO操作及Flag包的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07

最新評論

达日县| 壤塘县| 荔浦县| 喀喇沁旗| 泸定县| 环江| 宁津县| 桂平市| 紫金县| 吉安县| 太仓市| 鄂伦春自治旗| 确山县| 济宁市| 龙里县| 绿春县| 盐源县| 上杭县| 德化县| 大宁县| 乃东县| 东莞市| 嘉荫县| 永宁县| 上饶县| 乌鲁木齐市| 孙吴县| 永兴县| 根河市| 湖南省| 乌兰察布市| 页游| 兴业县| 沙河市| 乐平市| 恭城| 如皋市| 南城县| 靖边县| 尤溪县| 稷山县|