当前位置: 首页 > 工具软件 > gjson > 使用案例 >

go中decode 和 json.Marshal的区别 以及 gjson工具

呼延鹏云
2023-12-01

go中decode 和 json.Marshal的区别 以及 gjson工具

简介

在Go语言中,当我们需要进行 JSON 编码或解码时,我们可以使用标准库 encoding 包中的 json 包。

json 包为我们提供了一系列的方法进行 json 编解码,比如解析时使用的 NewDecoder() 和 Decode() 方法,以及将结构类型或 map 类型编码为 json 字符串的 Marshal() 方法,解析 json 字符串的 Unmarshal() 方法。

下面先从一个例子入手,然后总结,最后做出区别。区别参考直接看这个连接Go JSON 编码和解码

使用举例

main.go

如下例子,使用了 encoding/json中的 json.Unmarshal来将json字符串解析到map 或者利用go的反射解析到对应结构体中,以及使用一个gjson工具

(参考:gjson:在Go中快速解析JSON $ go get -u github.com/tidwall/gjson )

package main

import (
	"encoding/json"
	"log"

	"github.com/tidwall/gjson"
)

// 嵌套一个对象
type Info struct {
	age int `json:"age"`
}

// 嵌套一个对象数组
type Extra struct {
	Address string `json:"address"`
}

// 定义需要反序列化的结构体
type UserRequest struct {
	Name     string  `json:"userName"`  // 通过tag里面的json,来指定json字符串中该字段的值从那里解析,不需要和字段名一样
	NickName string  `json:"nick_name"` // 如果没对应上,解析不了
	info     Info    `json:"info"`      // 小写私有的,故反序列化失效,该字段永远为空
	Extra    []Extra `json:"extra"`
}

func main() {
	jsonStr := `
	{
		"userName":"admin",
		"nick_name":"管理员",
		"info":{
		   "age":18
		},
		"extra":[
		   {
			  "address":"上海市"
		   },
		   {
			  "address":"北京市"
		   }
		]
	 }`

	// 方式一:序列化成map(不常用)
	anyMap := make(map[string]interface{}, 0)
	if err := json.Unmarshal([]byte(jsonStr), &anyMap); err != nil {
		panic(err)
	}
	log.Println("Unmarshal to map result:", anyMap)
    
    // 方式一扩展: 使用 NewDecoder将json字符串解析到map中,如下,对req.body进行解析,解析到map中
    // NewDecoder的参数是 io.Reader类型,而Unmarshal的参数为[]byte, 和any(任何类型)
    params := make(map[string]interface{})
    json.NewDecoder(req.body).Decode(&params)
    log.Println("NewDecoder decode to map result: ", params)

	// 方式二:序列化成对象,经常使用
	req := UserRequest{}
	if err := json.Unmarshal([]byte(jsonStr), &req); err != nil {
		panic(err)
	}
	log.Println("Unmarshal to struct:", req)
    // 方式二扩展,如果是从http的req body中读取,就只需要用ioutil.ReadAll(req.Body)即可
    // data, _ := ioutil.ReadAll(req.Body),然后将这个data替换到上面 []byte(jsonStr) 处即可
    
    

	// 方式三:不反序列化,只读取单个key,经常使用。适合特别复杂的json字符串,或者有多种if else结构的场景
	userName := gjson.Get(jsonStr, "userName")
	nickName := gjson.Get(jsonStr, "nick_name")
	age := gjson.Get(jsonStr, "info.age").Int()

	// 取得extra数组0位置的对象
	address1 := gjson.Get(jsonStr, "extra").Array()[1]
	log.Println("get raw value by key:", userName, nickName, age, address1.Get("address"))
}

总结

  • NewDecoder() 和 Decode() 用于解析 json 到结构类型或map类型

  • Unmarshal() 用于解析 json 字符串

  • Marshal() 或 MarshalIndent() 用于将结构类型或map类型解码为 json 字符串

以上就是本文所分享的全部内容,希望对你有所帮助。

 类似资料: