關于golang無法解析json的問題,在實際開發(fā)中是經常會遇到的。下面我們先來看一下具體的代碼:
package main import ( "encoding/json" "fmt" ) type Person struct { Name string `json:"name"` Age int `json:"age"` } func main() { p := &Person{Name: "Tom", Age: 18} b, _ := json.Marshal(p) fmt.Println(string(b)) //輸出:{"name":"Tom","age":18} var p1 Person err := json.Unmarshal(b, &p1) if err != nil { fmt.Println(err) } fmt.Println(p1.Name) //輸出:Tom fmt.Println(p1.Age) //輸出:0 }
從上面的代碼可以看出,我們定義了一個Person結構體,并使用json.Marshal將其編碼成json字符串,然后再使用json.Unmarshal將其解碼成一個Person結構體。但是最終輸出結果中,雖然Name字段成功解碼,但是Age字段并沒有解碼成功,其值為默認值0。
這是為什么呢?其實原因就在于我們定義了Person結構體中的Age字段為int類型。當json在解析Age字段時,如果字段值為null,則會導致Golang解析失敗,默認將其解析為int類型的0。所以我們在解析Json數(shù)據時,需要注意處理字段值為null的情況。
下面是一種解決方案:
type Person struct { Name string `json:"name"` Age *int `json:"age,omitempty"` } func main() { p := &Person{Name: "Tom", Age: new(int)} *p.Age = 18 b, _ := json.Marshal(p) fmt.Println(string(b)) //輸出:{"name":"Tom","age":18} var p1 Person err := json.Unmarshal(b, &p1) if err != nil { fmt.Println(err) } fmt.Println(p1.Name) //輸出:Tom fmt.Println(*p1.Age) //輸出:18 }
通過將Age字段的類型從int類型改為指針類型*int,并在其后面添加omitempty標簽,就可以處理字段值為null的情況了。當json解碼Age字段時,如果字段值為null,則會解析為nil,而不是默認值0。因此我們在使用的時候需要判定其是否為nil,以免引發(fā)nil指針異常。