Go 語言json.Unmarshal 遇到的小問題(推薦)
1.問題現(xiàn)象描述
使用 json.Unmarshal()
,反序列化時,出現(xiàn)了科學(xué)計數(shù)法,參考代碼如下:
jsonStr := `{"number":1234567}` result := make(map[string]interface{}) err := json.Unmarshal([]byte(jsonStr), &result) if err != nil { fmt.Println(err) } fmt.Println(result) // 輸出 // map[number:1.234567e+06]
這個問題不是必現(xiàn),只有當(dāng)數(shù)字的位數(shù)大于 6 位時,才會變成了科學(xué)計數(shù)法。
2.問題影響描述
當(dāng)數(shù)據(jù)結(jié)構(gòu)未知,使用 map[string]interface{}
來接收反序列化結(jié)果時,如果數(shù)字的位數(shù)大于 6 位,都會變成科學(xué)計數(shù)法,用到的地方都會受到影響。
3.引起問題的原因
從 encoding/json
可以找到答案,看一下這段注釋:
// To unmarshal JSON into an interface value, // Unmarshal stores one of these in the interface value: // // bool, for JSON booleans // float64, for JSON numbers // string, for JSON strings // []interface{}, for JSON arrays // map[string]interface{}, for JSON objects // nil for JSON null
是因為當(dāng) JSON
中存在一個比較大的數(shù)字時,它會被解析成 float64
類型,就有可能會出現(xiàn)科學(xué)計數(shù)法的形式。
4.問題的解決方案
方案一
強制類型轉(zhuǎn)換,參考代碼如下:
jsonStr := `{"number":1234567}` result := make(map[string]interface{}) err := json.Unmarshal([]byte(jsonStr), &result) if err != nil { fmt.Println(err) } fmt.Println(int(result["number"].(float64))) // 輸出 // 1234567
方案二
盡量避免使用 interface
,對 json
字符串結(jié)構(gòu)定義結(jié)構(gòu)體,快捷方法可使用在線工具:https://mholt.github.io/json-to-go/
。
type Num struct { Number int `json:"number"` } jsonStr := `{"number":1234567}` var result Num err := json.Unmarshal([]byte(jsonStr), &result) if err != nil { fmt.Println(err) } fmt.Println(result) // 輸出 // {1234567}
方案三
使用 UseNumber()
方法。
jsonStr := `{"number":1234567}` result := make(map[string]interface{}) d := json.NewDecoder(bytes.NewReader([]byte(jsonStr))) d.UseNumber() err := d.Decode(&result) if err != nil { fmt.Println(err) } fmt.Println(result) // 輸出 // map[number:1234567]
這時一定要注意 result["number"]
的數(shù)據(jù)類型!
fmt.Println(fmt.Sprintf("type: %v", reflect.TypeOf(result["number"]))) // 輸出 // type: json.Number
通過代碼可以看出 json.Number
其實就是字符串類型:
// A Number represents a JSON number literal. type Number string
如果轉(zhuǎn)換其他類型,參考如下代碼:
// 轉(zhuǎn)成 int64 numInt, _ := result["number"].(json.Number).Int64() fmt.Println(fmt.Sprintf("value: %v, type: %v", numInt, reflect.TypeOf(numInt))) // 輸出 // value: 1234567, type: int64 // 轉(zhuǎn)成 string numStr := result["number"].(json.Number).String() fmt.Println(fmt.Sprintf("value: %v, type: %v", numStr, reflect.TypeOf(numStr))) // 輸出 // value: 1234567, type: string
到此這篇關(guān)于Go 語言json.Unmarshal 遇到的小問題(推薦)的文章就介紹到這了,更多相關(guān)Go 語言json.Unmarshal內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Hugo?Config模塊構(gòu)建實現(xiàn)源碼剖析
這篇文章主要為大家介紹了Hugo?Config模塊構(gòu)建實現(xiàn)源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02goFrame的隊列g(shù)queue對比channel使用詳解
這篇文章主要為大家介紹了goFrame的gqueue對比channel使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06