這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Encode
golang和json的類型對應關係如下:
- bool類型 -- JSON的Boolean
- 整數,浮點數等數實值型別 -- JSON的Number
- string -- JSON的字串(帶""引號)
- struct -- JSON的Object (再根據各個成員的類型遞迴打包)
- 數組或切片 -- JSON的Array
- []byte -- 會先進行base64編碼然後轉換為JSON字串
- map -- JSON的Object。key必須是string
- interface{} -- 按照內部的實際類型進行轉換
- nil -- JSON的null
- channel,func等類型 -- 返回UnsupportedTypeError
在golang中,encoding/json包下函數Marshal可以將結構體編碼為json格式
func Marshal(in interface{}) (out []byte, err error)
type Student struct { Name string Age int Sex string}func main() { var stu = Student{"dtc", 22, "boy"} //將結構體封裝成json格式,並返回[]byte j, err := json.Marshal(stu) if err != nil { fmt.Errorf("Marshal Error %v", err) } fmt.Println(string(j))}output: {"Name":"dtc","Age":22,"Sex":"boy"}
結構體中大寫開頭的變數才可以被json處理,小寫開頭不會被處理
Decode
encoding/json包下函數Unmarshal可以將json解碼為struct
Mashal時,結構體的成員變數名將會直接作為JSON Object的key打包成JSON(前提是struct中的變數首字母大寫);Unmashal時,會自動匹配對應的變數名進行賦值,大小寫不敏感(前提是struct中的變數首字母大寫)
func Unmarshal(p []byte, v interface{}) error
type Student struct { Name string AgE int sex string}func main() { str := []byte(`{"name":"hiehie","age":22,"sex":"girl"}`) var stu Student err := json.Unmarshal(str, &stu) if err != nil { fmt.Println(err) } fmt.Println(stu)}output: {hiehie 22 }
StructTag
可以通過打標籤的方式手動的配置struct變數和json欄位之間的關係。
type Student struct { Name string `json:"stu_name"` Age int `json:"stu_age"` Sex string `json:"stu_sex"`}func main() { str := []byte(`{"stu_name":"hiehie","stu_age":22,"stu_sex":"girl"}`) var stu Student err := json.Unmarshal(str, &stu) if err != nil { fmt.Println(err) } fmt.Println(stu)}output: {hiehie 22 girl}
type Student struct { Name string `json:"stu_name"` Age int `json:"stu_age"` Sex string `json:"stu_sex"`}func main() { var stu Student = Student{Name: "gigi", Age: 22, Sex: "girl"} s, err := json.Marshal(stu) if err != nil { fmt.Println(err) } fmt.Println(string(s))}output: {"stu_name":"gigi","stu_age":22,"stu_sex":"girl"}
tag中設定omitempty,如果該欄位為nil或零值,則打包的JSON結果不會有這個欄位。想要忽略的欄位,可以在tag中設定為"-"
type Student struct { Name string `json:"stu_name"` Age int `json:"stu_age,omitempty"` Sex string `json:"-"`}func main() { var stu Student = Student{Name: "kk", Age: 0, Sex: "girl"} s, err := json.Marshal(stu) if err != nil { fmt.Println(err) } fmt.Println(string(s))}output: {"stu_name":"kk"}
interface{}
在不知道JSON資料的格式時,struct中的類型可以使用interface{}。
interface{}類型在Unmarshal時,會自動將JSON轉換為對應的資料類型:
- JSON的boolean 轉換為bool
- JSON的數值 轉換為float64
- JSON的字串 轉換為string
- JSON的Array 轉換為[]interface{}
- JSON的Object 轉換為map[string]interface{}
- JSON的null 轉換為nil
type Student struct { Name interface{} `json:"name"` Age interface{} `json:"age"` Sex interface{} `json:"sex"`}func main() { str := []byte(`{"name":"kk","age":22,"sex":"girl"}`) stu := new(Student) err := json.Unmarshal(str, stu) if err != nil { fmt.Println(err) } fmt.Println(*stu)}output:{kk 22 girl}