1. Description of problem phenomenon
usejson.Unmarshal()
, during deserialization, the scientific counting method appears, and the reference code is as follows:
jsonStr := `{"number":1234567}`
result := make(map[string]interface{})
err := json.Unmarshal([]byte(jsonStr), &result)
if err != nil {
fmt.Println(err)
}
fmt.Println(result)
//Output
// map[number:1.234567e+06]
This problem is not inevitable. Only when the number of digits is greater than 6, it will become a scientific counting method.
2. Problem impact description
When the data structure is unknown, usemap[string]interface{}
When receiving deserialization results, if the number of digits is greater than 6, it will become a scientific counting method, and the places used will be affected.
3. Causes of problems
fromencoding/json
You can find the answer. Take a look at this note:
// 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
Because whenJSON
When there is a large number in, it will be parsed intofloat64
Type, there may be the form of scientific counting.
4. Solutions to problems
Scheme I
Cast type, reference code is as follows:
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)))
//Output
// 1234567
Scheme II
Try to avoid usinginterface
Yesjson
The string structure defines the structure. The shortcut method can use the online tool: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)
//Output
// {1234567}
Programme III
useUseNumber()
method.
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)
//Output
// map[number:1234567]
Be careful at this timeresult["number"]
Data type!
fmt.Println(fmt.Sprintf("type: %v", reflect.TypeOf(result["number"])))
//Output
// type: json.Number
As can be seen from the codejson.Number
It’s actually a string type:
// A Number represents a JSON number literal.
type Number string
If converting other types, refer to the following code:
//Convert to Int64
numInt, _ := result["number"].(json.Number).Int64()
fmt.Println(fmt.Sprintf("value: %v, type: %v", numInt, reflect.TypeOf(numInt)))
//Output
// value: 1234567, type: int64
//Convert to string
numStr := result["number"].(json.Number).String()
fmt.Println(fmt.Sprintf("value: %v, type: %v", numStr, reflect.TypeOf(numStr)))
//Output
// value: 1234567, type: string