文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang中omitempty关键字怎么用

2023-06-26 06:55

关注

本篇内容介绍了“Golang中omitempty关键字怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

用法

熟悉 Golang 的朋友对于 json 和 struct 之间的转换一定不陌生,为了将代码中的结构体与 json 数据解耦,通常我们会在结构体的 field 类型后加上解释说明,例如在表示一个地址的时候, json 数据如下所示

{    "street": "200 Larkin St",    "city": "San Francisco",    "state": "CA",    "zipcode": "94102"}

与之相对应的 Golang 结构体表示可能是这个样子的

type address struct {    Street  string `json:"street"`  // 街道    Ste     string `json:"suite"`   // 单元(可以不存在)    City    string `json:"city"`    // 城市    State   string `json:"state"`   // 州/省    Zipcode string `json:"zipcode"` // 邮编}

这样无论代码中的变量如何改变,我们都能成功将 json 数据解析出来,获得正确的街道,城市等信息,到目前为止一切正常。但如果我们想要将地址结构体恢复成 json 格式时,问题就来了。比方说我们用下面这段代码读取了地址 json ,然后根据业务逻辑处理了之后恢复成正常的 json 打印出来

func main() {        data := `{        "street": "200 Larkin St",        "city": "San Francisco",        "state": "CA",        "zipcode": "94102"    }`    addr := new(address)    json.Unmarshal([]byte(data), &addr)        // 处理了一番 addr 变量...    addressBytes, _ := json.MarshalIndent(addr, "", "    ")    fmt.Printf("%s\n", string(addressBytes))}

这段代码的输出是

{    "street": "200 Larkin St",    "suite": "",    "city": "San Francisco",    "state": "CA",    "zipcode": "94102"}

多了一行 "suite": "", ,而这则信息在原本的 json 数据中是没有的(在美国的地址中,如果不是群租公寓或者共享办公楼, suite 这一条不存在很正常,人们直接用街道门牌号来表示地址就足够了),但我们更希望的是,在一个地址有 suite 号码的时候输出,不存在 suite 的时候就不输出,幸运的是,我们可以在 Golang 的结构体定义中添加 omitempty 关键字,来表示这条信息如果没有提供,在序列化成 json 的时候就不要包含其默认值。稍作修改,地址结构体就变成了

type address struct {    Street  string `json:"street"`    Ste     string `json:"suite,omitempty"`    City    string `json:"city"`    State   string `json:"state"`    Zipcode string `json:"zipcode"`}

重新运行,即可得到正确的结果。

陷阱

带来方便的同时,使用 omitempty 也有些小陷阱,一个是该关键字无法忽略掉嵌套结构体。还是拿地址类型说事,这回我们想要往地址结构体中加一个新 field 来表示经纬度,如果没有缺乏相关的数据,暂时可以忽略。新的 struct 定义如下所示

type address struct {    Street     string     `json:"street"`    Ste        string     `json:"suite,omitempty"`    City       string     `json:"city"`    State      string     `json:"state"`    Zipcode    string     `json:"zipcode"`    Coordinate coordinate `json:"coordinate,omitempty"`}type coordinate struct {    Lat float64 `json:"latitude"`    Lng float64 `json:"longitude"`}

读入原来的地址数据,处理后序列化输出,我们就会发现即使加上了 omitempty 关键字,输出的 json 还是带上了一个空的坐标信息

{    "street": "200 Larkin St",    "city": "San Francisco",    "state": "CA",    "zipcode": "94102",    "coordinate": {        "latitude": 0,        "longitude": 0    }}

为了达到我们想要的效果,可以把坐标定义为指针类型,这样 Golang 就能知道一个指针的“空值”是多少了,否则面对一个我们自定义的结构, Golang 是猜不出我们想要的空值的。于是有了如下的结构体定义

type address struct {    Street     string      `json:"street"`    Ste        string      `json:"suite,omitempty"`    City       string      `json:"city"`    State      string      `json:"state"`    Zipcode    string      `json:"zipcode"`    Coordinate *coordinate `json:"coordinate,omitempty"`}type coordinate struct {    Lat float64 `json:"latitude"`    Lng float64 `json:"longitude"`}

相应的输出为

{    "street": "200 Larkin St",    "city": "San Francisco",    "state": "CA",    "zipcode": "94102"}

另一个“陷阱”是,对于用 omitempty 定义的 field ,如果给它赋的值恰好等于默认空值的话,在转为 json 之后也不会输出这个 field 。比如说上面定义的经纬度坐标结构体,如果我们将经纬度两个 field 都加上 omitempty

type coordinate struct {    Lat float64 `json:"latitude,omitempty"`    Lng float64 `json:"longitude,omitempty"`}

然后我们对非洲几内亚湾的“原点坐标”非常感兴趣,于是编写了如下代码

func main() {    cData := `{        "latitude": 0.0,        "longitude": 0.0    }`    c := new(coordinate)    json.Unmarshal([]byte(cData), &c)        // 具体处理逻辑...    coordinateBytes, _ := json.MarshalIndent(c, "", "    ")    fmt.Printf("%s\n", string(coordinateBytes))}

最终我们得到了一个

{}

这个坐标消失不见了!但我们的设想是,如果一个地点没有经纬度信息,则悬空,这没有问题,但对于“原点坐标”,我们在确切知道它的经纬度的情况下,(0.0, 0.0)仍然被忽略了。正确的写法也是将结构体内的定义改为指针

type coordinate struct {    Lat *float64 `json:"latitude,omitempty"`    Lng *float64 `json:"longitude,omitempty"`}

这样空值就从 float64 的 0.0 变为了指针类型的 nil ,我们就能看到正确的经纬度输出。

{    "latitude": 0,    "longitude": 0}

“Golang中omitempty关键字怎么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯