I’ve been writing some dynamic languages before, and I think parsing JSON is very easy. It usually takes only a few lines of code to get a parsed JSON object. The Go json package allows you to easily read and write JSON data in your application. Generating a JSON scenario is relatively simple. Json.marshal () generates THE JSON data based on the structure that is passed in. Parsing JSON parses the data into structures, and because of the free-grouping nature of the JSON format, especially complex JSON data, it can be confusing for novices to declare the types of structures to accept JSON data. In my recent work, I had to parse JSON data persisted by JS and PHP programs, so it took me about two afternoons to figure out how to declare structure types for common JSON data. The following are the details.
Parsing simple JSON
package main
import (
"fmt"
"encoding/json"
"time"
)
func main() {
type FruitBasket struct {
Name string
Fruit []string
Id int64 `json:"ref"} jsonData := []byte(' {"Name": "Standard"."Fruit": [
"Apple"."Banana"."Orange"]."ref": 999,
"Created": "2018-04-09T23:00:00Z"
}`)
var basket FruitBasket
err := json.Unmarshal(jsonData, &basket)
iferr ! = nil { fmt.Println(err) } fmt.Println(basket.Name, basket.Fruit, basket.Id) fmt.Println(basket.Created) }Copy the code
Note: due to json. The UnMarshal () method receives the byte slices, so first need to convert a json string to byte section c: = [] byte (s) Playground url: play.golang.org/p/mcB6Kb6zC…
Parse JSON for an embedded object
“Fruit” : {“Name”, “Apple”, “PriceTag”: “$1”}
jsonData := []byte(`
{
"Name": "Standard"."Fruit" : {"Name": "Apple"."PriceTag": "The $1"},
"ref": 999,
"Created": "2018-04-09T23:00:00Z"} `)Copy the code
So the structure type should be declared like this
type Fruit struct {
Name string `json":Name"`
PriceTag string `json:"PriceTag"`}type FruitBasket struct {
Name string
Fruit Fruit
Id int64 `json:"ref"'// declare a json key Created time.time}Copy the code
Playground url: play.golang.org/p/dqw6tLb4J…
Parse JSON(Embed Array of Object)
If the Fruit value in the JSON object above is now
"Fruit": [{"Name": "Apple"."PriceTag": "The $1"
},
{
"Name": "Pear"."PriceTag": "The $15 ".}]Copy the code
In this case, simply change the parse JSON structure to []Fruit
type Fruit struct {
Name string `json:"Name"`
PriceTag string `json:"PriceTag"`}type FruitBasket struct {
Name string
Fruit []Fruit
Id int64 `json:"ref"'// declare a json key Created time.time}Copy the code
Parse a JSON object with a dynamic Key
Let’s do a complex workaround. If we change the above array of objects to an object of object whose Key is the ID of the fruit, for example
"Fruit" : {
"1": {
"Name": "Apple"."PriceTag": "The $1"
},
"2": {
"Name": "Pear"."PriceTag": "The $15 ".}}Copy the code
So how do we declare a Fruit field as a map with a Key of type string and a value of type Fruit
type Fruit struct {
Name string `json:"Name"`
PriceTag string `json:"PriceTag"`}type FruitBasket struct {
Name string
Fruit map[string]Fruit
Id int64 `json:"ref"'// declare a json key Created time.time}Copy the code
The sample code
package main
import (
"fmt"
"encoding/json"
"time"
)
func main() {
type Fruit struct {
Name string `json:"Name"`
PriceTag string `json:"PriceTag"`}type FruitBasket struct {
Name string
Fruit map[string]Fruit
Id int64 `json:"ref"} jsonData := []byte(' {"Name": "Standard"."Fruit" : {
"1": {
"Name": "Apple"."PriceTag": "The $1"
},
"2": {
"Name": "Pear"."PriceTag": "The $15 ".}},"ref": 999,
"Created": "2018-04-09T23:00:00Z"
}`)
var basket FruitBasket
err := json.Unmarshal(jsonData, &basket)
iferr ! = nil { fmt.Println(err) }for _, item := range basket.Fruit {
fmt.Println(item.Name, item.PriceTag)
}
}
Copy the code
Playground url: play.golang.org/p/fh8JKa6pK…
Parsing JSON data containing arbitrary arrays and objects
The encode/ JSON package also provides an alternative way to parse JSON data, as it is difficult to declare structure types for JSON data containing any hierarchy. The encoding/json package uses:
- Map [string]interface{} Stores JSON objects
- []interface Stores a JSON array
Js.unmarshl will store any valid JSON data into a value of type Interface {}. By using the null interface type we can store any value, but using this type as a value requires a type assertion first.
Example code:
jsonData := []byte(`{"Name":"Eve"."Age": 6,"Parents": ["Alice"."Bob"]}`)
var v interface{}
json.Unmarshal(jsonData, &v)
data := v.(map[string]interface{})
for k, v := range data {
switch v := v.(type) {
case string:
fmt.Println(k, v, "(string)")
case float64:
fmt.Println(k, v, "(float64)")
case []interface{}:
fmt.Println(k, "(array):")
for i, u := range v {
fmt.Println("", i, u)
}
default:
fmt.Println(k, v, "(unknown)")}}Copy the code
Although storing JSON data in an empty interface type can be used to parse JSON data of any structure, there are still some uncontrollable areas in practical application, such as converting numeric string values to float values, so the type assertion error is often reported when running. Therefore, in the case of the JSON structure is determined, it is preferred to use the structure type declaration, JSON data into the structure of the way to parse JSON.