【轉】protoc-go-inject-tag 作用


 

原文:https://www.jianshu.com/p/744d8c080d59

----------------------------

 

protobuf導出golang,調整默認tag的方法

問題概述

在protobuf導出到golang的時候,生成的.go文件里的struct的tag是沒辦法靈活設置的,以下面這個message為例




test.proto

syntax=proto3;
package test;

option go_package = ".;test";

message MyMessage {
    int64 Code = 1;
}

執行protoc --proto_path=. --go_out=. test.proto導出的test.pb.go里的MyMessage這個結構體的定義會是這樣:

type MyMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Code int64 `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"` } 

可以看到Code字段的protobuf和json的tag都是固定的(目前還沒有找到方法能通過protoc命令的參數來設置tag),但是這樣的struct有時候並不是我們所期待的,比如下面的代碼片段:

msg := &MyMessage{Code: 0} bdata, _ := json.Marshal(msg) fmt.Println(string(bdata)) 

這段代碼最終的輸出會是{},因為Code的json tag設置了omitempty,這種情況在開發過程中有時候是很蛋疼的,因為即便Code是默認值0,我們也還是希望能打印出來的。因此我們需要一種方法能通過在編寫proto文件的時候,在里面注入tag,然后導出成go的時候這個被注入的字段的tag可以自定義。

解決方法

test.proto

syntax=proto3; package test; option go_package = ".;test"; message MyMessage { // @inject_tag: json:"Code" int64 Code = 1; } 

可以看到與之前不同的是我們在Code這個字段上面加了一行注釋// @inject_tag: json:"Code"
執行

protoc --proto_path=. --go_out=. test.proto
protoprotoc-go-inject-tag -input=./test.pb.go

這時候導出的test.pb.go文件里的MyMessage結構體如下:

type MyMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // @inject_tag: json:"Code" Code int64 `protobuf:"varint,1,opt,name=Code,proto3" json:"Code"` } 

可以看到Code字段的json tag里的omitempty沒有了,這時候如果我們再執行

msg := &MyMessage{Code: 0} bdata, _ := json.Marshal(msg) fmt.Println(string(bdata)) 

這個代碼片段,輸出就是{"Code": 0}了。達到我們的目的了。當然inject_tag不僅僅可以設置json的tag,它可以設置任何的tag。

總結

protobuf的protoc工具導出golang的時候,導出的結構體的tag是固定死的,在實際的使用中會導致很多不方便或是不靈活,通過protoc-go-inject-tag這個工具,可以inject tag,這樣就能靈活的調整導出的pb.go文件里的結構體的tag。



作者:大菜狗RookieDog
鏈接:https://www.jianshu.com/p/744d8c080d59
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM