ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-03-01 11:01:33  阅读:228  来源: 互联网

标签:protoc test json tag inject go Code


 

原文: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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:protoc,test,json,tag,inject,go,Code
来源: https://www.cnblogs.com/oxspirt/p/15949195.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有