相关推荐recommended
【Golang | json】golang解析json数据的4种方法
作者:mmseoamin日期:2024-01-25

现在有一个json格式的字符串,应该怎么解析呢,这里总结了以下4种方法

1. json.Unmarshal

函数func json.Unmarshal(data []byte, v any) error就是用来解析json编码的data,然后将结果保存在指针v指向的值里

e.g.

package main
import (
	"encoding/json"
	"fmt"
)
type user struct {
	Name    string
	Married bool
	Address struct {
		City    string
		Country string
	}
}
func main() {
	user1 := `{
		"name": "tian",
		"married": false,
		"address": {
		  "city": "beijing",
		  "country": "China"
		}
	  }`
	user1Struct := &user{}
	json.Unmarshal([]byte(user1), user1Struct)
	fmt.Printf("解码后的结果为:%v", *user1Struct)
}
  • 首先根据json数据的格式定义struct,用来保存解码后的值。这里首先定义了一个user结构体,然后通过json.Unmarshal进行解码
  • 缺点很明显,如果json数据很复杂,自定义的struct就跟着复杂。

    程序运行后的结果如下:

    PS E:\goland-workspace\GolangLearning\Common\json数据处理\unmarshal> go run .\main.go
    解码后的结果为:{tian false {beijing China}}
    

    2. viper.ReadConfig

    使用go get -u github.com/spf13/viper 进行下载

    函数func viper.ReadConfig(in io.Reader) error用于从in中读取数据并解析

    e.g.

    package main
    import (
    	"fmt"
    	"strings"
    	"github.com/spf13/viper"
    )
    func main() {
    	user1 := `{
    		"name": "tian",
    		"married": false,
    		"address": {
    		  "city": "beijing",
    		  "country": "China"
    		}
    	  }`
    	// 指定配置的类型为json
    	viper.SetConfigType("json")
    	// 读取数据
    	if err := viper.ReadConfig(strings.NewReader(user1)); err != nil {
    		fmt.Println(err)
    	}
    	fmt.Printf("数据的所有键值: %v\n", viper.AllKeys())
    	fmt.Printf("解析后的数据:%v\n", viper.AllSettings())
    	fmt.Printf("the type of \"married\" is %s\n", reflect.TypeOf(viper.Get("married")))
    	fmt.Printf("The name is %s and the country is %s\n", viper.Get("name"), viper.Get("address.country"))
    }
    
    • 首先要通过viper.SetConfigType("json")指定要解析数据的格式,否则即使viper.ReadConfig返回值没有报错,也得不到解析后的结果。可以查看https://github.com/spf13/viper/issues/316
    • 方法viper.Get(),viper.GetString(),viper.GetBool()等等可以方便获取键值,同时对于键值的类型也能很好的判断

      程序运行后的结果如下:

      PS E:\goland-workspace\GolangLearning\Common\json数据处理\viper> go run .\main.go
      数据的所有键值: [address.city address.country name married]
      解析后的数据:map[address:map[city:beijing country:China] married:false name:tian]
      the type of "married" is bool
      The name is tian and the country is China
      

      3. simplejson.NewJson

      使用go get -u "github.com/bitly/go-simplejson"进行下载

      e.g.

      package main
      import (
      	"fmt"
      	"github.com/bitly/go-simplejson"
      )
      func main() {
      	user1 := `{
      		"name": "tian",
      		"married": false,
      		"address": {
      		  "city": "beijing",
      		  "country": "China"
      		}
      	  }`
      	user1json, err := simplejson.NewJson([]byte(user1))
      	if err != nil {
      		fmt.Println(err)
      	}
      	name1, _ := user1json.Get("name").String()
      	city1, _ := user1json.Get("address").Get("city").String()
      	fmt.Printf("The name is %s and the city is %s", name1, city1)
      }
      

      程序运行后的结果如下:

      PS E:\goland-workspace\GolangLearning\Common\json数据处理\simpleJson> go run .\main.go
      The name is tian and the city is beijing
      

      4. gojsonq.New().FromString()

      使用go get -u github.com/thedevsaddam/gojsonq安装

      e.g.

      package main
      import (
      	"fmt"
      	"github.com/thedevsaddam/gojsonq/v2"
      )
      func main() {
      	user1 := `{
      		"name": "tian",
      		"married": false,
      		"address": {
      		  "city": "beijing",
      		  "country": "China"
      		}
      	  }`
      	user1json := gojsonq.New().FromString(user1)
      	name1 := user1json.Find("name").(string)
      	user1json.Reset()
      	city1 := user1json.Find("address.city")
      	fmt.Printf("The name is %s and the city is %v", name1, city1)
      }