长整型数字精度丢失
import (
"bytes"
"encoding/json"
)
...
const userJson=`{"name":"Harvey","id":1514889703642370048}`
userInfo map[string]interface{}
infoBytes := []byte(userJson)
json.Unmarshal(infoBytes, &userInfo)
// json数值类型被定义为 interface{}, 使用 Unmarshal 方法后,只能被断言为float64
uid := userInfo["id"].(float64)
func JsonDecodeUseNumber(infoBytes []byte, result interface{}) error {
decoder := json.NewDecoder(bytes.NewReader(infoBytes))
// 未设置UseNumber, 长整型会丢失精度
decoder.UseNumber()
return decoder.Decode(result)
}
JsonDecodeUseNumber(infoBytes, &userInfo)
uidJNum := userInfo["id"].(json.Number)
uid := uidJNum.Int64()
...
json
没有整型和浮点型之分, 只有Number
数值类型json
中的Number
字段,如果被定义为interface{}
, 使用json.Unmarshal
方法将被解析为float64
- 使用
UseNumber()
方法,将interface{}
类型,转为json.Number
类型
该问题实质为 IEEE754
二进制浮点数算术标准(ANSI/IEEE Std 754-1985)的问题。
json字符串包含非法字符
json.Unmarshal 解压报错: json.Unmarshal invalid character '\n' in string literal
import (
"bytes"
"encoding/json"
)
...
prodJson := `{"hel": "doafd",
"xxxdf": "aoifjadfoweih"}`
prodBytes := []byte(prodJson)
for i, ch := range prodBytes {
switch {
case ch > '~':
prodBytes[i] = ' '
case ch == '\r', ch == '\n', ch == '\t', ch < ' ':
prodBytes[i] = ' '
}
}
pd := map[string]string{}
json.Unmarshal(prodBytes, &pd)
...
golang——Json分级解析及数字解析实践 https://www.jianshu.com/p/8b64bb06d522
Go 易采坑总结 https://www.liuin.cn/2018/08/23/Go-%E6%98%93%E9%87%87%E5%9D%91%E6%80%BB%E7%BB%93/
深入理解 Go Json.Unmarshal 精度丢失之谜 https://developer.51cto.com/article/697019.html