GO語言練習:構建json 和 解析JSON 實例

本文介紹如何使用Go語言自帶的庫把對象轉換爲JSON格式,並在channel中進行傳輸後,並把JSON格式的信息轉換回對象。json

一、Go語言的JSON 庫數組

  Go語言自帶的JSON轉換庫爲 encoding/json數據結構

 

  1.1)其中把對象轉換爲JSON的方法(函數)爲 json.Marshal(),其函數原型以下函數

    func Marshal(v  interface{}) ([]byte, error)編碼

    也就是說,這個函數接收任意類型的數據 v,並轉換爲字節數組類型,返回值就是咱們想要的JSON數據和一個錯誤代碼。當轉換成功的時候,這個錯誤代碼爲nilspa

    在進行對象轉換爲 JSON 的過程當中,會遵循以下幾條規則:指針

    • 布爾型轉換爲 JSON 後還是布爾型 , 如true -> truecode

    • 浮點型和整數型轉換後爲JSON裏面的常規數字,如 1.23 -> 1.23對象

    • 字符串將以UTF-8編碼轉化輸出爲Unicode字符集的字符串,特殊字符好比<將會被轉義爲\u003cblog

    • 數組和切片被轉換爲JSON 裏面的數組,[]byte類會被轉換爲base64編碼後的字符串,slice的零值被轉換爲null

    • 結構體會轉化爲JSON對象,而且只有結構體裏邊以大寫字母開頭的可被導出的字段纔會被轉化輸出,而這些可導出的字段會做爲JSON對象的字符串索引

    • 轉化一個map 類型的數據結構時,該數據的類型必須是 map[string]T(T 能夠是encoding/json 包支持的任意數據類型)

 

  1.2)把 JSON 轉換回對象的方法(函數)爲 json.Unmarshal(),其函數原型以下

    func Unmarshal(data [] byte, v interface{}) error

    這個函數會把傳入的 data 做爲一個JSON來進行解析,解析後的數據存儲在參數 中。這個參數 v 也是任意類型的參數(但必定是一個類型的指針),緣由是咱們在是以此函數進行JSON 解析的時候,這個函數不知道這個傳入參數的具體類型,因此它須要接收全部的類型。

    那麼,在進行解析的時候,若是JSON 和 對象的結構不對口會發生什麼呢,這就須要解析函數json.Unmarshal()遵循如下規則

    • json.Unmarshal() 函數會根據一個約定的順序查找目標結構中的字段,若是找到一個即發生匹配。那什麼是找到了呢?關於「找到了」又有以下的規則:假設一個JSON對象有個名爲"Foo"的索引,要將"Foo"所對應的值填充到目標結構體的目標字段上,json.Unmarshal() 將會遵循以下順序進行查找匹配

      § 一個包含Foo 標籤的字段

      §  一個名爲Foo 的字段

      § 一個名爲Foo 或者Foo 或者除了首字母其餘字母不區分大小寫的名爲Foo 的字段。 這些字段在類型聲明中必須都是以大寫字母開頭、可被導出的字段。

    注意:若是JSON中的字段在Go目標類型中不存在,json.Unmarshal() 函數在解碼過程當中會丟棄該字段。

    • 當JSON 的結構是未知的時候,會遵循以下規則:

      § JSON中的布爾值將會轉換爲Go中的bool類型

      § 數值會被轉換爲Go中的float64類型

      § 字符串轉換後仍是string類型

      § JSON數組會轉換爲[]interface{} 類型

      § JSON對象會轉換爲map[string]interface{}類型

      § null值會轉換爲nil

    注意:在Go的標準庫encoding/json包中,容許使用map[string]interface{}和[]interface{} 類型的值來分別存放未知結構的JSON對象或數組


 

二、代碼實例

  假設咱們有以下一個類(結構體)student 及其一個實例對象st:

type Student struct {
    Name    string
    Age     int
    Guake   bool
    Classes []string
    Price   float32
}

st := &Student {
    "Xiao Ming",
    16,
    true,
    []string{"Math", "English", "Chinese"},
     9.99,
}

  如今咱們須要把這個類的一個對象轉換爲JSON格式,而且傳輸給遠方的朋友,那麼咱們就能夠這麼作:

b, err := json.Marshal(st)

  這樣就轉換好了。是否是很簡單!轉換回來就更簡單了,好比咱們有一個新的student對象,就叫stb,那麼咱們能夠這樣轉換回來:

stb := &Student{}
err = json.Unmarshal([]byte(strData), &stb)

  這樣就轉換回來了,是否是很簡單!

下面是完整代碼及運行結果:

$ cat gojson.go 

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "encoding/json"
 6 )
 7 
 8 type Student struct {
 9     Name    string
10     Age        int
11     Guake    bool
12     Classes    []string
13     Price    float32
14 }
15 
16 func (s * Student)ShowStu() {
17     fmt.Println("show Student :")
18     fmt.Println("\tName\t:", s.Name)
19     fmt.Println("\tAge\t:", s.Age)
20     fmt.Println("\tGuake\t:", s.Guake)
21     fmt.Println("\tPrice\t:", s.Price)
22     fmt.Printf("\tClasses\t: ")
23     for _, a := range s.Classes {
24         fmt.Printf("%s ", a)
25     }
26     fmt.Println("")
27 }
28 
29 func main() {
30     st := &Student {
31         "Xiao Ming",
32         16,
33         true,
34         []string{"Math", "English", "Chinese"},
35         9.99,
36     }
37     fmt.Println("before JSON encoding :")
38     st.ShowStu()
39 
40     b, err := json.Marshal(st)
41     if err != nil {
42         fmt.Println("encoding faild")
43     } else {
44         fmt.Println("encoded data : ")
45         fmt.Println(b)
46         fmt.Println(string(b))
47     }
48     ch := make(chan string, 1)
49     go func(c chan string, str string){
50         c <- str
51     }(ch, string(b))
52     strData := <-ch
53     fmt.Println("--------------------------------")
54     stb := &Student{}
55     stb.ShowStu()
56     err = json.Unmarshal([]byte(strData), &stb)
57     if err != nil {
58         fmt.Println("Unmarshal faild")
59     } else {
60         fmt.Println("Unmarshal success")
61         stb.ShowStu()
62     }
63 }

運行結果:

$ go run  gojson.go 
before JSON encoding :
show Student :
    Name    : Xiao Ming
    Age    : 16
    Guake    : true
    Price    : 9.99
    Classes    : Math English Chinese 
encoded data : 
[123 34 78 97 109 101 34 58 34 88 105 97 111 32 77 105 110 103 34 44 34 65 103 101 34 58 49 54 44 34 71 117 97 107 101 34 58 116 114 117 101 44 34 67 108 97 115 115 101 115 34 58 91 34 77 97 116 104 34 44 34 69 110 103 108 105 115 104 34 44 34 67 104 105 110 101 115 101 34 93 44 34 80 114 105 99 101 34 58 57 46 57 57 125]
{"Name":"Xiao Ming","Age":16,"Guake":true,"Classes":["Math","English","Chinese"],"Price":9.99}
--------------------------------
show Student :
    Name    : 
    Age    : 0
    Guake    : false
    Price    : 0
    Classes    : 
Unmarshal success
show Student :
    Name    : Xiao Ming
    Age    : 16
    Guake    : true
    Price    : 9.99
    Classes    : Math English Chinese

 

做者:風波

mail : fengbohello@qq.com

相關文章
相關標籤/搜索