美文网首页
golang unmarshal 踩坑指北

golang unmarshal 踩坑指北

作者: 米兰的小铁匠xxm | 来源:发表于2022-04-01 22:05 被阅读0次

问题描述:

在实际工作中,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]

相关文章

网友评论

      本文标题:golang unmarshal 踩坑指北

      本文链接:https://www.haomeiwen.com/subject/bekzjrtx.html