在 golang 中使用 Json

序列化

序列化對象將使用 encoding/json 中的 Marshal 函數。golang

函數原型爲:func Marshal(v interface{}) ([]byte, error)json

如下是官網給出的例子:函數

package main

import (
    "encoding/json"
    "fmt"
    "os"
)

func main() {
    type ColorGroup struct {
        ID     int
        Name   string
        Colors []string
    }
    group := ColorGroup{
        ID:     1,
        Name:   "Reds",
        Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
    }
    b, err := json.Marshal(group)
    if err != nil {
        fmt.Println("error:", err)
    }
    os.Stdout.Write(b)
}

須要注意的是:json.Marshal返回了[]byte類型,一般狀況下,須要將其轉換爲string類型使用。指針

反序列化

反序列化對象將使用 encoding/json 中的 Unmarshal 函數。code

函數原型爲:func Unmarshal(data []byte, v interface{}) error對象

如下是官網給出的例子:遞歸

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]`)
    type Animal struct {
        Name  string
        Order string
    }
    var animals []Animal
    err := json.Unmarshal(jsonBlob, &animals)
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Printf("%+v", animals)
}

在反序列化時,有可能不知道Json數據的具體類型,那應該怎麼辦呢?rem

其實,觀察json.Unmarshal的函數原型能夠看到,其第二個參數是一個interface。get

事實上,你能夠傳入一個interface對象的指針,反序列化函數依然會填充這個對象。而且這個對象能夠被轉換成爲map[string]interface{}這樣的類型或者[]interface{}這樣的類型,這取決於Json的內容。原型

因而,咱們便有了在不知道Json數據具體類型的狀況下,解析Json內容的方法。

代碼以下:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]`)

    var jsonObject interface{}
    err := json.Unmarshal(jsonBlob, &jsonObject)
    if err != nil {
        fmt.Println("error:", err)
    }
    animals := jsonObject.([]interface{})
    for i := 0; i < len(animals); i++ {
        animalObject := animals[i]
        animalMap := animalObject.(map[string]interface{})
        fmt.Println(animalMap["Name"])
        fmt.Println(animalMap["Order"])
    }
}

如上,咱們能夠將反序列化出的對象,遞歸地進行類型轉換,轉換爲[]interface{}或者map[string]interface{},這樣就能一層層地解析Json的內容了。

固然,以上只是舉例,證實能夠經過一些手段解析未知結構的Json。爲了正確解析未知結構的Json內容,你可能須要爲解析過程添加一些判斷,如解析出的對象的類型須要二選一,又如解析出的map類型中鍵的存在性等等。

相關文章
相關標籤/搜索