本文是《Golang 升级之路》系列第一篇。

参考文章:

  1. 说一说go mod
  2. Go语言的Json管理模式
  3. golang omitempty实现嵌套结构体的省略输出

go mod介绍

go mod 是 go 的主流依赖管理工具(类似于 Node.js 的 npm、Java 的 maven),go1.13版本已支持,安装相关的内容可以参考这篇文章:说一说go mod,以下总结常用的一些 go mod 命令:

  1. # 初始化当前目录为模块根目录,生成go.mod, go.sum文件
  2. go mod init
  3. # 下载依赖包
  4. go mod download
  5. # 整理检查依赖,如果缺失包会下载或者引用的不需要的包会删除
  6. go mod tidy
  7. # 复制依赖到vendor目录下面
  8. go mod vendor
  9. # 可看完整所有的命令
  10. go mod
  11. # 删除不需要的依赖包、下载新的依赖包、更新go.sum
  12. go mod tidy

结构体JSON转换

omitempty——缺省修饰

  1. 使用 omitempty 修饰结构体中的字段,在把结构体转换 JSON 时,如果该字段值是空值(比如: false、0、””、nil 指针、nil 接口、长度为0的数组、切片、映射),则不会输出该字段,例如: ```go package main

import ( “encoding/json” “fmt” )

type Activity struct { ID int json:"id" TagID int json:"tagID,omitempty" Cover string json:"cover" Description string json:"description,omitempty" Title string json:"title" TypeID int json:"typeID" Status int json:"status" CreateAt string json:"createAt" }

func main() { activityItem := Activity{ ID: 430, TagID: 0, Cover: “//qiniu-cdn.wbu-bit1.online/1591242437643.jpg”, Description: “”, Title: “哈吉斯店庆”, TypeID: 6, Status: 1, CreateAt: “2020-08-24 10:17:15”, }

  1. activityJSON, err := json.Marshal(activityItem)
  2. if err != nil {
  3. fmt.Println(err)
  4. } else {
  5. fmt.Println(string(activityJSON))
  6. }

}

  1. 以上代码打印出的 activityJSON 内容为:
  2. ```json
  3. {
  4. "id": 430,
  5. "cover": "//qiniu-cdn.wbu-bit1.online/1591242437643.jpg",
  6. "title": "哈吉斯店庆",
  7. "typeID": 6,
  8. "status": 1,
  9. "createAt": "2020-08-24 10:17:15"
  10. }

可以发现输出的 JSON 不包含 tagID、description 两个字段,因为这两个字段都用 omitempty 修饰且其值皆为空。

需要注意,如果结构体A内含有结构体B类型的字段并用 omitempty 修饰,如果不给该字段进行任何赋值操作,输出的 JSON 仍然会包含一个结构体B的默认 JSON 数据元,而不是忽略其输出,例如:

  1. ...
  2. type Activity struct {
  3. ID int `json:"id"`
  4. TagInfo Tag `json:"tagInfo,omitempty"`
  5. ...
  6. }
  7. type Tag struct {
  8. ID int `json:"id"`
  9. Name string `json:"name"`
  10. }
  11. func main() {
  12. activityItem := Activity{
  13. ID: 430,
  14. Cover: "//qiniu-cdn.wbu-bit1.online/1591242437643.jpg",
  15. Description: "",
  16. Title: "哈吉斯店庆",
  17. TypeID: 6,
  18. Status: 1,
  19. CreateAt: "2020-08-24 10:17:15",
  20. }
  21. ...
  22. }

以上代码,我将原 Activity 结构体中的 TagID 字段改成了 TagInfo 字段,其数据类型是结构体 Tag,并移除 activityItem 中的 TagID 的赋值,同时不对 TagInfo 进行赋值操作,此时输出的 JSON 内容如下:

  1. {
  2. "id": 430,
  3. "tagInfo": {
  4. "id": 0,
  5. "name": ""
  6. },
  7. "cover": "//qiniu-cdn.wbu-bit1.online/1591242437643.jpg",
  8. "title": "哈吉斯店庆",
  9. "typeID": 6,
  10. "status": 1,
  11. "createAt": "2020-08-24 10:17:15"
  12. }

可见其仍会输出一个表征空值的 tagInfo 字段。

如果要实现结构体字段为空时不输出默认值,可以通过指针实现,只需进行以下操作:

  1. ...
  2. type Activity struct {
  3. ...
  4. TagInfo *Tag `json:"tagInfo,omitempty"` // 将类型设置为指针
  5. ...
  6. }
  7. ...