JSON

概述 #

encoding/json 包含了 JSON 相关处理方法。

例子 #

结构体转为 JSON 字符串 #

调用 json.Marshal() 方法完成。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	addr string `json:"addr"` // 该属性转 JSON 时会被忽略
}

func main() {
	tom := person{ // 使用字面量初始化
		Name: "Tom",
		Age:  6,
		addr: "???",
	}

	tomJson, err := json.Marshal(tom)
	if err != nil {
		panic(err)
	}
	fmt.Printf("json.Marshal(tom) = %s\n", tomJson) // 从输出字符串中可以看到,并没有 addr 属性
}

// $ go run main.go
// 输出如下 
/**
  json.Marshal(tom) = {"name":"Tom","age":6}
*/

JSON 字符串转为结构体 #

调用 json.Unmarshal() 方法完成。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
	addr string `json:"addr"` // 该属性转 json 时会被忽略
}

func main() {
	// 注意: JSON 字符串格式一定要正确,否则会报错
	tomJson := `
{
  "name": "Tom",
  "age": 6,
  "addr": "???"
}
`
	var tom person
	err := json.Unmarshal([]byte(tomJson), &tom)
	if err != nil {
		panic(err)
	}

	// 从输出字符串中可以看到,并没有为 addr 属性赋值
	fmt.Printf("Tom's name is %s, age is %d, addr is %s\n", tom.Name, tom.Age, tom.addr)
}

// $ go run main.go
// 输出如下 
/**
  Tom's name is Tom, age is 6, addr is
*/

输出格式化 JSON 字符串 #

调用 json.MarshalIndent() 方法完成。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name  string   `json:"name"`
	Age   int      `json:"age"`
	Hobby []string `json:"hobby"`
}

func main() {
	tom := person{ // 使用字面量初始化
		Name: "Tom",
		Age:  6,
		Hobby: []string{
			"reading",
			"coding",
			"movie",
		},
	}

	// 前缀符为空字符串,缩进符为两个空格
	formatted, err := json.MarshalIndent(tom, "", "  ")
	if err != nil {
		panic(err)
	}

	fmt.Printf("json.MarshalIndent(tom) = \n%s\n", formatted)
}

// $ go run main.go
// 输出如下 
/**
  json.MarshalIndent(tom) =
  {
    "name": "Tom",
    "age": 6,
    "hobby": [
      "reading",
      "coding",
      "movie"
    ]
  }
*/

忽略零值 #

通过 omitempty 关键字完成。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name  string   `json:"name"`
	Age   int      `json:"age"`
	Hobby []string `json:"hobby,omitempty"` // omitempty 关键字将字段标记为忽略零值
}

func main() {
	tom := person{ // 使用字面量初始化
		Name: "Tom",
		Age:  6,
	}

	// 前缀符为空字符串,缩进符为两个空格
	formatted, err := json.MarshalIndent(tom, "", "  ")
	if err != nil {
		panic(err)
	}

	fmt.Printf("json.MarshalIndent(tom) = \n%s\n", formatted)
}

// $ go run main.go
// 输出如下 
/**
  json.MarshalIndent(tom) =
  {
    "name": "Tom",
    "age": 6
  }
*/

保留零值 #

某些场景下,需要在输出 JSON 字符串时自动忽略零值,但是在将 JSON 字符串转为目标结构体时,需要保留零值。 可以通过将字段设置为 指针 类型即可。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name     string `json:"name"`
	Age      int    `json:"age"`
	HasMoney *bool  `json:"hasMoney,omitempty"`
}

func main() {
	tomJson := `
{
  "name": "Tom",
  "age": 6,
  "hasMoney": false
}
`
	var tom person
	err := json.Unmarshal([]byte(tomJson), &tom)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Tom's name is %s, age is %d, hasMoney is %t\n", tom.Name, tom.Age, *tom.HasMoney)
}

// $ go run main.go
// 输出如下 
/**
  Tom's name is Tom, age is 6, hasMoney is false
*/

忽略公开值 #

某些场景下,需要将结构体字段设置为公开可导出,但是又不希望 JSON 序列化时输出该字段, 可以使用 - 符号标识。

package main

import (
	"encoding/json"
	"fmt"
)

type person struct {
	Name  string   `json:"name"`
	Age   int      `json:"age"`
	Hobby []string `json:"-"`
}

func main() {
	tom := person{ // 使用字面量初始化
		Name: "Tom",
		Age:  6,
		Hobby: []string{
			"reading",
			"coding",
			"movie",
		},
	}

	// 前缀符为空字符串,缩进符为两个空格
	formatted, err := json.MarshalIndent(tom, "", "  ")
	if err != nil {
		panic(err)
	}

	fmt.Printf("json.MarshalIndent(tom) = \n%s\n", formatted)
}

// $ go run main.go
// 输出如下 
/**
  json.MarshalIndent(tom) =
  {
    "name": "Tom",
    "age": 6
  }
*/

转载申请

本作品采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,商业转载请联系作者获得授权。

© 蛮荆 | 陕公网安备 61011302001681 号 | 陕ICP备2023004378号-1 | Rendered by Hugo