The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
shadow7

go proto3 过滤零值

  •  
  •   shadow7 · Aug 3, 2022 · 3101 views
    This topic created in 1408 days ago, the information mentioned may be changed or developed.

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

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

    15 replies    2022-08-03 21:21:27 +08:00
    tairan2006
        1
    tairan2006  
       Aug 3, 2022   ❤️ 1
    ls *.pb.go | xargs -n1 -IX bash -c 'sed s/,omitempty// X > X.tmp && mv X{.tmp,}'
    tairan2006
        2
    tairan2006  
       Aug 3, 2022   ❤️ 2
    或者:

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

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

    可能需要关注你 client 端为什么反序列化出来没有这个字段。按理说,它反序列化时也会把零值自动填回来,该有的字段还是有的。
    所以需要你补充解释「 api 请求 rpc server 出来的时候零值的字段是不存在的」
    shadow7
        9
    shadow7  
    OP
       Aug 3, 2022
    @tairan2006 我去掉了,但是零值的字段还是没有, 不知道怎么回事
    kalista
        10
    kalista  
       Aug 3, 2022
    没有太理解 op 的意思,猜测是想 print 时候有零值字段?那应该从打印函数着手,我提供一个序列化为 json 的做法
    kalista
        11
    kalista  
       Aug 3, 2022
    ```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
    }
    ```
    shadow7
        12
    shadow7  
    OP
       Aug 3, 2022
    @tairan2006 好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
    shadow7
        13
    shadow7  
    OP
       Aug 3, 2022   ❤️ 1
    @twistedmeadows 好了,谢谢,我在 server 端去掉的,应该在 client 端去掉。是我没理解透彻,谢谢指导
    shadow7
        14
    shadow7  
    OP
       Aug 3, 2022
    @kalista 可以了 谢谢
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5414 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 53ms · UTC 07:53 · PVG 15:53 · LAX 00:53 · JFK 03:53
    ♥ Do have faith in what you're doing.