golang 1.13 Value.IsZero 值得期待的地方

2019-10-11 09:34:20 +08:00
 guonaihong

随着 go1.13 发布,reflect 包里新加了 IsZero 函数。随着该函数的加入,可能会解决一个遗留问题。

go version

go version go1.13.1 linux/amd64

问题请看

在 json 编码里面,如果打上 omitempty,值为空是不会输出内容的

package main

import (
    "fmt"
    //"reflect"
    "encoding/json"
    "time"
)

type test struct {
    Tm time.Time `json:"tm,omitempty"`
    X  int       `json:"x,omitempty"`
    Y  int 
}

func main() {
    all, err := json.Marshal(test{})
    fmt.Printf("%s, %v\n", all, err)
}

/*
输出 {"tm":"0001-01-01T00:00:00Z","Y":0}, <nil>
*/

这什么情况? omitempty 没用 难道对结构体使用没有作用,tm 里面竟然有东西?我们加个自定义结构体再看下(time.Time 的实现方式是结构体)。

package main

import (
    "encoding/json"
    "fmt"
    //"reflect"
    "time"
)

type mystruct struct {
    I int `json:"i,omitempty"`
    J int `json:"j,omitempty"`
}

type test struct {
    Tm time.Time `json:"tm,omitempty"`
    X  int       `json:"x,omitempty"`
    Y  int

    M mystruct `json:"m,omitempty"`
}

func main() {
    all, err := json.Marshal(test{})
    fmt.Printf("%s, %v\n", all, err)

    //fmt.Printf("%t\n", reflect.ValueOf(test{}).IsZero())
}

/*
{"tm":"0001-01-01T00:00:00Z","Y":0,"m":{}}, <nil>
*/

自定义结构体声明的 m 字段有值,在这个版本里面 omitempty 遇到结构体还是没起作用。

回到正题

随着 Value.IsZero 的加入,在未来的 go 版本上面的问题有可能得到解决。打开上面代码的注释, 会发现 reflect.ValueOf(test{}).IsZero()输出为 true。在 json 编码器检测到 omitempty 字段,再调用下 reflect.ValueOf(xxx).IsZero(),忽略这个字段就行。

在现有的版本如何解决这个问题

github

https://github.com/guonaihong/gout

3198 次点击
所在节点    程序员
4 条回复
Reficul
2019-10-11 11:05:01 +08:00
诶,辣么要是这个字段的值就是 0 咋办: 即预期希望输出 {"Y":0}。

如果 JSON 标准库加上这个 feature,是不是会破坏已有的兼容,应该这样的改动不会进吧。

所以。。。。老老实实使用指针吧。。。。
guonaihong
2019-10-11 12:41:14 +08:00
@Reficul 未来 go 如果通过这个 feature。可以通过 omitempty 字段控制,加了才忽略。用指针还要判断指针为空的情况,用起来还是挺累的。

if p == nil {
return
}
Reficul
2019-10-11 12:57:59 +08:00
@guonaihong

Y= nil 的时候忽略,和 Y = 0 (默认值)的时候忽略是不一样的呀。

比如你输出的这个 JSON 里希望这个值在某种场景下是不返回的,则忽略;但是在某种场景下需要返回,但是值就是 0 则不希望忽略。
guonaihong
2019-10-11 13:16:03 +08:00
@Reficul 恩,这个需求只能用指针。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/608096

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX