问题描述:
在实际工作中,map中存储字段类型可能不同,所以我们将map定义为map[string]interface{}类型,结果遇到了map中整数变成科学技术法的问题,示例代码如下:
func main() {
m := map[string]interface{}{
"number": 1234566,
"is_number": true,
}
mStr, _ := json.Marshal(m)
n := make(map[string]interface{})
if err := json.Unmarshal(mStr, &n); err != nil {
fmt.Println(err)
}
fmt.Println(n)
}
//输出 map[is_number:true number:1.234566e+06]
测试发现当整数的长度小于等于6位时,却能正常解析,代码如下:
func main() {
m := map[string]interface{}{
"number": 123456,
"is_number": true,
}
mStr, _ := json.Marshal(m)
n := make(map[string]interface{})
if err := json.Unmarshal(mStr, &n); err != nil {
fmt.Println(err)
}
fmt.Println(n)
}
//输出 map[is_number:true number:123456]
原因分析:
查看下marshal的使用说明
// Otherwise, Marshal uses the following type-dependent default encodings:
//
// Boolean values encode as JSON booleans.
//
// Floating point, integer, and Number values encode as JSON numbers.
//
// String values encode as JSON strings coerced to valid UTF-8,
可以看到浮点数、整数和number类型都会被转为 json number
再翻看unmarshal的使用说明
// 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
从官方注释可以看到,json numbers会被转为float类型,至此解释了为啥成为科学计数法。
解决方案:
使用usenumber
func main() {
m := map[string]interface{}{
"number": 123445678,
"is_number": true,
}
n := make(map[string]interface{})
mStr, _ := json.Marshal(m)
docoder := json.NewDecoder(strings.NewReader(string(mStr)))
docoder.UseNumber()
_ = docoder.Decode(&n)
fmt.Println(n)
}
//输出 map[is_number:true number:123445678]
网友评论