本文介紹如何使用Go語言自帶的庫把對象轉換為JSON格式,並在channel中進行傳輸后,並把JSON格式的信息轉換回對象。
1、Go語言的JSON 庫
Go語言自帶的JSON轉換庫為 encoding/json
1.1)其中把對象轉換為JSON的方法(函數)為 json.Marshal(),其函數原型如下
func Marshal(v interface{}) ([]byte, error)
也就是說,這個函數接收任意類型的數據 v,並轉換為字節數組類型,返回值就是我們想要的JSON數據和一個錯誤代碼。當轉換成功的時候,這個錯誤代碼為nil
在進行對象轉換為 JSON 的過程中,會遵循如下幾條規則:
• 布爾型轉換為 JSON 后仍是布爾型 , 如true -> true
• 浮點型和整數型轉換后為JSON里面的常規數字,如 1.23 -> 1.23
• 字符串將以UTF-8編碼轉化輸出為Unicode字符集的字符串,特殊字符比如<將會被轉義為\u003c
• 數組和切片被轉換為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 中。這個參數 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對象或數組
2、代碼實例
假設我們有如下一個類(結構體)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