当用enconding/json包的时候,数字默认是处理为float64类型的,这就导致了int64可能会丢失精度

举个例子

1
2
3
4
5
6
7
8
9
10
11
func err() {
s := "{\"id\": 1153273393983037404}"
mm := make(map[string]interface{})

_ = json.Unmarshal([]byte(s), &mm)
jstr, _ := json.Marshal(mm)
fmt.Println(string(jstr))
}

###
{"id":1153273393983037400}

本来json里面的id是1153273393983037404,转成interface{}后会变成float64类型,再转回json的时候精度丢失就发生了

解决方案

  1. 直接用string存,然后自行用strconv转换

  2. 使用json.decoder来替换Unmarshal,其实底层也是用string存,不过是封装好了的。。,上个实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    func right() {
    s := "{\"id\": 1153273393983037404}"
    mm := make(map[string]interface{})
    decoder := json.NewDecoder(bytes.NewReader([]byte(s)))
    decoder.UseNumber()
    _ = decoder.Decode(&mm)
    fmt.Println(mm)
    jstr, _ := json.Marshal(mm)
    fmt.Println(string(jstr))
    }

    ###
    map[id:1153273393983037404]
    {"id":1153273393983037404}