protobuf导出go时调整默认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可以自定义。
解决方法
- protoc-go-inject-tag: https://github.com/favadi/protoc-go-inject-tag
- 安装:go get https://github.com/favadi/protoc-go-inject-tag
- 这个库可以在proto文件中注入tag,然后在导出的时候相应的字段的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。
本文作者:oaoa
本文链接:https://www.cnblogs.com/oaoa/p/17342303.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步