Golang笔记:使用json包处理JSON数据

文章目录

  • 目的
  • Decoding(解析数据)
  • Encoding(创建数据)
  • 总结

目的

JSON 是一种非常流行的数据交换格式,是JavaScript中原生支持的一种数据,因为其简单方便,所以也经常用在不同程序、不同语言间数据交互。这篇文章将介绍在Golang中使用JSON相关内容( encoding/json )。

Decoding(解析数据)

可以使用 encoding/json 包的 func Unmarshal(data []byte, v any) error 方法,从原始JSON字符串中解析对应内容到指定数据结构中。比如下面示例将解析数据到结构体中:

package main

import (
	"encoding/json"
	"fmt"
)

type data struct {
	Num int    `json:"num"`
	Bl  bool   `json:"bl"`
	Str string `json:"str"`
	Arr []int  `json:"arr"`
	Obj struct {
		Num int `json:"num"`
	} `json:"obj"`
} // 用于接收JSON字符串中内容的结构体类型

func main() {
	var j data
	s := `{
		"num": 233,
		"bl": true,
		"str": "naisu",
		"arr": [
		  22,
		  33
		],
		"obj": {
		  "num": 777
		}
	  }` // 原始JSON字符串

	json.Unmarshal([]byte(s), &j) // 从原始数据中解析内容填充结构体对象

	fmt.Println(j.Num, j.Bl, j.Str, j.Arr, j.Obj)
}

在这里插入图片描述
上面例子操作比较简单,但是演示了JSON的几种基本的数据格式。需要注意的是 结构体中字段名称首字母需要大写

如果有现成的JSON数据范本的话可以通过下面工具直接生成结构体类型声明:
https://mholt.github.io/json-to-go/

上面演示中结构体类型中字段和原始JSON数据中字段是可以一一匹配上的,但如果两者无法一一匹配,也可以进行解析。 结构体中有而JSON中没有的字段,那么解析之后结构体对象中这些字段将会填充默认值。结构体中没有而JSON中有的字段,那么解析时会忽略这些字段。

上面方式对于已知格式的JSON数据解析时比较好用,但是对于未知格式的JSON数据解析就不太好用了。通常可以使用泛型来处理,比如可以使用 map[string]interface{} 接收对象,使用 []interface{} 接收数组。请看下面示例:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	var j map[string]interface{}

	s := `{
		"num": 233,
		"bl": true,
		"str": "naisu",
		"arr": [
		  22,
		  33
		],
		"obj": {
		  "num": 777
		}
	  }` // 原始JSON字符串

	if err := json.Unmarshal([]byte(s), &j); err != nil {
		fmt.Println(err)
	}

	fmt.Println(j)

	for k, v := range j {
		switch vv := v.(type) {
		case bool:
			fmt.Println(k, "is bool", vv)
		case string:
			fmt.Println(k, "is string", vv)
		case float64:
			fmt.Println(k, "is float64", vv)
		case []interface{}:
			fmt.Println(k, "is array:")
			for i, u := range vv {
				fmt.Println(i, u)
			}
		case map[string]interface{}:
			fmt.Println(k, "is oject:", v)
		default:
			fmt.Println(k, "is of a type I don't know how to handle")
		}
	}
}

Golang笔记:使用json包处理JSON数据_第1张图片

现在有泛型了, interface{} 也可以使用 any 来代替。

Encoding(创建数据)

可以使用 encoding/json 包的 func Marshal(v any) ([]byte, error) 方法将Golang数据类型生成JSON字符串。比如下面例子:

package main

import (
	"encoding/json"
	"fmt"
)

type data struct {
	Num int    `json:"num"`
	Bl  bool   `json:"bl"`
	Str string `json:"str"`
	Arr []int  `json:"arr"`
	Obj struct {
		Num int `json:"num"`
	} `json:"obj"`
} // 用于接收JSON字符串中内容的结构体类型

func main() {
	j := data{
		Num: 233,
		Bl:  true,
		Str: "naisu",
	}
	j.Arr = append(j.Arr, 22, 33)
	j.Obj.Num = 777

	b, err := json.Marshal(j) // 将结构体转换成JSON字符串
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(b))
}

在这里插入图片描述

数据也可以通过接口或泛型等类型进行转换:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	j := make(map[string]any)
	j["Num"] = 233
	j["Bl"] = true
	j["Str"] = "naisu"
	Arr := []int{}
	Arr = append(Arr, 22, 33)
	j["Arr"] = Arr
	Obj := make(map[string]any)
	Obj["Num"] = 777
	j["Obj"] = Obj

	b, err := json.Marshal(j) // 将结构体转换成JSON字符串
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(b))
}

在这里插入图片描述

总结

对于JSON的操作主要内容就是这些了。如果需要更加细节的解析和创建的控制可以使用 MarshalJSON 或者 UnmarshalJSON 等方法。

你可能感兴趣的:(编程相关,笔记,json,golang,对象,js)