Golang Go语言中 proto3 过滤零值
go proto3 生成的文件,微服务接口会过滤掉零值字段,这个有什么好的解决方式吗?
比如我定义了 name age 两个字段,如果 age 是 0 ,name 返回的时候只有 name 字段,这样不太友好。
Golang Go语言中 proto3 过滤零值
ls *.pb.go | xargs -n1 -IX bash -c ‘sed s/,omitempty// X > X.tmp && mv X{.tmp,}’
更多关于Golang Go语言中 proto3 过滤零值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
0 是作为默认值的,可以减少序列化以后的体积大小,当你反序列化以后,创建出来的数据结构里面的 age 字段在没有设置的时候,也是 0 值,所以从结果上来看是没有什么影响的。
protocol buffer 其实表现力很弱, 自己要额外做很多工作才能用舒服了
我这边用 api 请求 rpc server 出来的时候零值的字段是不存在的,我在 server 端打印的时候就发现零值字段没有,是我哪里写的不对吗
第一个我试过不行, 我再试试 可能我哪里写错了,谢谢
你直接用 ide 把所有,omitempty 删掉也行
如果我没理解错,这是 protobuffer 自己的特性,任何语言版本的 protobuffer 都会这样省略 0 值来减少传输。
可能需要关注你 client 端为什么反序列化出来没有这个字段。按理说,它反序列化时也会把零值自动填回来,该有的字段还是有的。
所以需要你补充解释「 api 请求 rpc server 出来的时候零值的字段是不存在的」
我去掉了,但是零值的字段还是没有, 不知道怎么回事
没有太理解 op 的意思,猜测是想 print 时候有零值字段?那应该从打印函数着手,我提供一个序列化为 json 的做法
go <br> var data bytes.Buffer<br> var jsonMarshal = &jsonpb.Marshaler{<br> EnumsAsInts: false,<br> EmitDefaults: true,<br> Indent: "",<br> OrigName: false,<br> AnyResolver: nil,<br> }<br> err := jsonMarshal.Marshal(&data, pb)<br> if err != nil {<br> return err<br> }<br>
好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
可以了 谢谢
在Golang中使用proto3时,过滤零值(zero values)是一个常见的需求,尤其是在序列化和反序列化protobuf消息时。Proto3的默认行为是不会将零值字段包含在序列化后的数据中。这种行为有助于减少数据的大小并提升效率。
对于基本数据类型(如int32, float, bool等),零值分别是0, 0.0, false等。对于字符串类型,空字符串("")被视为零值。对于消息类型,未设置的字段(即未明确赋值的字段)也被视为零值。
如果你希望在序列化时包含某些零值字段,可以通过以下几种方式实现:
-
使用
oneof
:如果字段的值是可选的,并且你希望区分字段是否设置(即使设置为零值),可以使用oneof
关键字。 -
自定义序列化逻辑:在序列化之前,手动检查字段值,并根据需要设置一些标志位或包装类型,以区分零值和未设置的情况。
-
使用Wrapper类型:对于基本数据类型,protobuf提供了Wrapper类型(如
google.protobuf.Int32Value
),这些类型可以显式地表示字段是否被设置。
请注意,修改protobuf的默认行为(即包含零值字段)可能会增加序列化后的数据大小,并可能影响性能。因此,在设计protobuf消息时,应仔细考虑是否需要包含零值字段,并在必要时使用上述技术。
希望这些信息对你有所帮助!如果有更多问题,欢迎继续讨论。