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

目的

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")
		}
	}
}

在这里插入图片描述

现在有泛型了, 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 等方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
[第一例 留言板][第二例 gRPC使用例子][第三例 基于go-micro做服务注册和服务发现][第四例 聊天室][第五例 工具库][第六例 原生sql操作][第七例 sqlx操作][第八例 Redis数据库(gomodule/redigo)][第九例 Redis消息队列][第十例 Redis集群连接][十一例 Zookeeper操作][十二例 Kafka操作][十三例 NSQ操作][十四例 二分查找][十五例 交换排序 - 冒泡排序][十六例 插入排序 - 直接插入排序][十七例 插入排序 - 希尔排序][十八例 交换排序 - 快速排序][十九例 算法求解应用][二十例 pprof性能分析][二一例 CPU信息采集][二二例 Heap信息采集][二三例 Http信息采集][二四例 单元测试(功能测试)][二五例 基准测试(压力测试/性能测试)][二六例 gdb调试][二七例 json序列化和反序列化][二八例 protobuf序列化和反序列化][二九例 管理工具 go vendor][三十例 管理工具 go mod][三一例 zip压缩][三二例 交叉编译][三三例 线上环境部署][三四例 实现固定周期维护][三五例 聊天室(精简版)][三六例 并发安全字典][三七例 导出Excel表格][三八例 导出CSV表格][三九例 聊天室(高并发)][四十例 JWT (Json Web Token)][四一例 雪花算法生成 Id][四二例 对称加密 AES][四三例 非对称加密 RSA][四四例 签名算法 SHA1][四五例 数据库操作 gorm][四六例 数据库操作 gorm 集合][四七例 RSA(MD5WithRSA 算法)签名和验签方式][四八例 线上部署脚本][四九例 Elasticsearch][五十例 对象池]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naisu Xu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值