V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
570956418
V2EX  ›  Go 编程语言

go proto3 过滤零值

  •  
  •   570956418 · 2022-08-03 13:21:21 +08:00 · 1962 次点击
    这是一个创建于 631 天前的主题,其中的信息可能已经有所发展或是发生改变。

    go proto3 生成的文件,微服务接口会过滤掉零值字段,这个有什么好的解决方式吗?

    比如我定义了 name age 两个字段,如果 age 是 0 ,name 返回的时候只有 name 字段,这样不太友好。

    15 条回复    2022-08-03 21:21:27 +08:00
    tairan2006
        1
    tairan2006  
       2022-08-03 13:23:55 +08:00   ❤️ 1
    ls *.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}'
    tairan2006
        2
    tairan2006  
       2022-08-03 13:26:39 +08:00   ❤️ 2
    或者:

    import "google.golang.org/protobuf/encoding/protojson"

    m := protojson.MarshalOptions{EmitUnpopulated: true}
    resp, err := m.Marshal(w)
    timethinker
        3
    timethinker  
       2022-08-03 13:28:57 +08:00   ❤️ 1
    0 是作为默认值的,可以减少序列化以后的体积大小,当你反序列化以后,创建出来的数据结构里面的 age 字段在没有设置的时候,也是 0 值,所以从结果上来看是没有什么影响的。
    dcoder
        4
    dcoder  
       2022-08-03 13:41:14 +08:00   ❤️ 1
    protocol buffer 其实表现力很弱, 自己要额外做很多工作才能用舒服了
    570956418
        5
    570956418  
    OP
       2022-08-03 13:52:06 +08:00
    @timethinker 我这边用 api 请求 rpc server 出来的时候零值的字段是不存在的,我在 server 端打印的时候就发现零值字段没有,是我哪里写的不对吗
    570956418
        6
    570956418  
    OP
       2022-08-03 13:52:45 +08:00
    @tairan2006 第一个我试过不行, 我再试试 可能我哪里写错了,谢谢
    tairan2006
        7
    tairan2006  
       2022-08-03 14:13:14 +08:00
    @570956418 你直接用 ide 把所有,omitempty 删掉也行
    twistedmeadows
        8
    twistedmeadows  
       2022-08-03 14:18:00 +08:00
    如果我没理解错,这是 protobuffer 自己的特性,任何语言版本的 protobuffer 都会这样省略 0 值来减少传输。

    可能需要关注你 client 端为什么反序列化出来没有这个字段。按理说,它反序列化时也会把零值自动填回来,该有的字段还是有的。
    所以需要你补充解释「 api 请求 rpc server 出来的时候零值的字段是不存在的」
    570956418
        9
    570956418  
    OP
       2022-08-03 14:31:05 +08:00
    @tairan2006 我去掉了,但是零值的字段还是没有, 不知道怎么回事
    kalista
        10
    kalista  
       2022-08-03 14:31:17 +08:00
    没有太理解 op 的意思,猜测是想 print 时候有零值字段?那应该从打印函数着手,我提供一个序列化为 json 的做法
    kalista
        11
    kalista  
       2022-08-03 14:31:33 +08:00
    ```go
    var data bytes.Buffer
    var jsonMarshal = &jsonpb.Marshaler{
    EnumsAsInts: false,
    EmitDefaults: true,
    Indent: "",
    OrigName: false,
    AnyResolver: nil,
    }
    err := jsonMarshal.Marshal(&data, pb)
    if err != nil {
    return err
    }
    ```
    570956418
        12
    570956418  
    OP
       2022-08-03 14:33:47 +08:00
    @tairan2006 好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
    570956418
        13
    570956418  
    OP
       2022-08-03 14:34:02 +08:00   ❤️ 1
    @twistedmeadows 好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
    570956418
        14
    570956418  
    OP
       2022-08-03 14:34:38 +08:00
    @kalista 可以了 谢谢
    czyt
        15
    czyt  
       2022-08-03 21:21:27 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3400 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:36 · PVG 19:36 · LAX 04:36 · JFK 07:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.