1. 程式人生 > >一.go語言 struct json相互轉換

一.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)
}