7

protobuf导出golang,调整默认tag的方法

 1 year ago
source link: https://studygolang.com/articles/28563?fr=sidebar
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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是固定死的,在实际的使用中会导致很多不方便或是不灵活,通过protoprotoc-go-inject-tag这个工具,可以inject tag,这样就能灵活的调整导出的pb.go文件里的结构体的tag。


有疑问加站长微信联系(非本文作者)

280

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK