Golang中omitempty关键字的具体实现
知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《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
}
P.S. 本文中拿来作示例的地址是旧金山亚洲艺术博物馆的地址,藏品丰富,上到夏商周,下至明清的文物都能看到,几年前第一次去参观,很是喜欢,印象深刻。
以上就是《Golang中omitempty关键字的具体实现》的详细内容,更多关于golang的资料请关注golang学习网公众号!
Golang语言JSON解码函数Unmarshal的使用
- 上一篇
- Golang语言JSON解码函数Unmarshal的使用
- 下一篇
- Go中JSON解析时tag的使用
-
- Golang · Go教程 | 28秒前 | golang 文件上传 文件保存 multipart/form-data ParseMultipartForm
- Golang文件上传教程与实现方法
- 197浏览 收藏
-
- Golang · Go教程 | 8分钟前 |
- Golang实现简易留言板系统教程
- 359浏览 收藏
-
- Golang · Go教程 | 31分钟前 |
- Golang并发测试与goroutine性能分析
- 456浏览 收藏
-
- Golang · Go教程 | 38分钟前 |
- Go语言scanner包:位移与空格识别解析
- 213浏览 收藏
-
- Golang · Go教程 | 41分钟前 |
- Golang适配器模式与接口转换技巧
- 371浏览 收藏
-
- Golang · Go教程 | 41分钟前 |
- Golang文件备份实现教程详解
- 105浏览 收藏
-
- Golang · Go教程 | 49分钟前 |
- Golang文件上传服务器搭建教程
- 125浏览 收藏
-
- Golang · Go教程 | 50分钟前 |
- Go语言自定义类型长度限制技巧
- 161浏览 收藏
-
- Golang · Go教程 | 52分钟前 |
- Golang反射实战教程详解
- 412浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- GolangCI/CD测试流程实现详解
- 347浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Golang模块冲突解决全攻略
- 200浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3168次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3381次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3410次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4514次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3790次使用
-
- Golang中omitempty的作用
- 2022-12-31 218浏览
-
- golang中json的omitempty使用操作
- 2022-12-30 466浏览

