一.go語言 struct json相互轉換
1.Go語言自帶JSON轉換庫 encoding/json
2.把物件轉換為json的方法為 json.Marshal(),其函式原型為:
func Marshal(v interface{}) ([]byte, error) { e := newEncodeState() err := e.marshal(v, encOpts{escapeHTML: true}) if err != nil { return nil, err } buf := append([]byte(nil), e.Bytes()...) e.Reset() encodeStatePool.Put(e)return buf, nil }
1) 函式可以接收任意型別的資料 v,並轉換為位元組陣列型別,返回值就是json資料和錯誤程式碼;若轉換成功,則err = nil;
2)在進行物件轉換為JSON的過程中,會遵循一下幾條原則:
1.布林型轉換為JSON後仍然是布林型;
2.浮點型轉換為JSON后里面的常規數字;
3.字串將以UTF-8編碼轉化輸出為Unicode字串,將特殊字元轉義;
4.陣列和切片被轉換為JSON裡面的陣列,[]byte類會被轉換為base64編碼後的字串,slice的零值被轉換為null;
5.結構體轉換為JSON物件,並且只有結構體內變數必須首字母大寫,才可被匯出的欄位轉化輸出,而且這些欄位會被作為JSON物件的字串索引;
6.轉換一個map型別的資料結構時,該資料的型別必須時map[string]T,T可以是encoding/json包支援的任意型別。
2.把JSON轉換回物件方法的方法為json.Unmarshal(),函式原型為:
func Unmarshal(data []byte, v interface{}) error { // Check for well-formedness. // Avoids filling out half a data structure // before discovering a JSON syntax error. var d decodeState err := checkValid(data, &d.scan) if err != nil { return err } d.init(data) return d.unmarshal(v) }
1)函式會把傳入的data作為一個JSON來進行解析,解析後的資料儲存在引數v中,這個引數可以是任意型別的引數(是一個型別的指標);
2)json.Umarshal()函式會根據一個約定的順序查詢結構中的欄位,如果找到一個即發生匹配。假設一個JSON物件有一個名為“Foo”的索引,要將“Foo”所對應的值填充到目標結構體的目標欄位上,json.Umarshal()將會遵循如下順序進行查詢匹配:
1.一個包含Foo標籤的欄位;
2.一個名為Foo的欄位
3.一個名為Foo或者除了首字母不區分大小寫的名為Foo的欄位,這些欄位在型別宣告中必須都是首字母大寫,可被匯出欄位。
注意:如果JSON中的欄位在Go目標型別中不存在,json,Umarshal()函式在解碼過程中會丟棄該欄位。
3)當JSON的結構位置時,會遵循一下規則:
1.JSON中的布林型將會轉換為Go中的bool型別;
2.數值將會被轉換為Go的float64型別;
3.字串轉換後是stirng型別;
4.JSON陣列將會轉換為[]interface{}型別
5.JSON物件會被轉換為map[stirng]interface{}型別;
6.null值會轉換為nil
注意:在Go的標準庫中encoding/json包中,允許使用map[stirng]interface{}和interface{}型別來分別儲存結構中的JSON物件和JSON陣列。
4.遇到問題,解決問題
1)接收JSON字串後,將其轉換為結構體,JSON字串中某一鍵值對,值型別為JSONArray,在結構體中宣告為string。在轉換之前將JSON中“properties”的值試圖轉換為string型別,最終失敗;最終在結構體中修改該變數型別為[]interface{},轉換成功。
{ "subjectId":"MathOperation", "subjectName":"數學運算", "subjectDispSerial":2, "subjectClass":"principal", "activityId":"Sum", "actDispSerial":1, "icon":"Sum.png", "modiTime":"2017-06-13 10:17:17", "funcGrp":"arithmetic", "author":"", "status":2, "properties":[ {"key":"nodeLabel","val":"","diapName":"節點標籤","editStyle":"TextField","dispSerial":10,"editable":true}, {"key":"subjectType","val":"數學運算","diapName":"所屬類別","editStyle":"TextField","dispSerial":20,"editable":false}, {"key":"nodeExplain","val":"","diapName":"節點說明","editStyle":"TextField","dispSerial":30,"editable":false}, {"key":"inputType","val":"Double[]","diapName":"輸入變數型別","editStyle":"ComboBox","dispSerial":40,"editable":true}, {"key":"outputType","val":"Double[]","diapName":"輸出變數型別","editStyle":"ComboBox","dispSerial":50,"editable":true}, {"key":"note","val":"","diapName":"備註","editStyle":"PluginDialog","dispSerial":1000,"editable":true} ], "inportInit":2, "inportMax":20, "outportInit":1, "outportMax":20, "topportInit":0, "topportMax":0, "bottomportInit":0, "bottomportMax":0, "note":"" }
type Activity struct { Id int SubjectId string SubjectName string SubjectDispSerial int SubjectClass string ActivityId string ActivityName string ActDispSerial int Icon string ModiTime string FuncGrp string Author string Status int Properties []interface{} InpotInit int InportMax int OutportInit int OutportMax int TopportInit int TopportMax int BottomportInit int BottomportMax int Note string }
var act models.Activity if err := json.Unmarshal([]byte(data), &act); err == nil { fmt.Println(act.SubjectId) fmt.Println(act.ActivityId) fmt.Println(act.Properties) } else { fmt.Println(err) }