时间:2021-05-23
1.问题现象描述
使用 json.Unmarshal(),反序列化时,出现了科学计数法,参考代码如下:
jsonStr := `{"number":1234567}`result := make(map[string]interface{})err := json.Unmarshal([]byte(jsonStr), &result)if err != nil { fmt.Println(err)}fmt.Println(result)// 输出// map[number:1.234567e+06]这个问题不是必现,只有当数字的位数大于 6 位时,才会变成了科学计数法。
2.问题影响描述
当数据结构未知,使用 map[string]interface{} 来接收反序列化结果时,如果数字的位数大于 6 位,都会变成科学计数法,用到的地方都会受到影响。
3.引起问题的原因
从 encoding/json 可以找到答案,看一下这段注释:
// 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 中存在一个比较大的数字时,它会被解析成 float64 类型,就有可能会出现科学计数法的形式。
4.问题的解决方案
方案一
强制类型转换,参考代码如下:
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)))// 输出// 1234567方案二
尽量避免使用 interface,对 json 字符串结构定义结构体,快捷方法可使用在线工具:https://mholt.github.io/json-to-go/。
type Num struct { Number int `json:"number"`}jsonStr := `{"number":1234567}`var result Numerr := json.Unmarshal([]byte(jsonStr), &result)if err != nil { fmt.Println(err)}fmt.Println(result)// 输出// {1234567}方案三
使用 UseNumber() 方法。
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)// 输出// map[number:1234567]这时一定要注意 result["number"] 的数据类型!
fmt.Println(fmt.Sprintf("type: %v", reflect.TypeOf(result["number"])))// 输出// type: json.Number通过代码可以看出 json.Number 其实就是字符串类型:
// A Number represents a JSON number literal.type Number string如果转换其他类型,参考如下代码:
// 转成 int64numInt, _ := result["number"].(json.Number).Int64()fmt.Println(fmt.Sprintf("value: %v, type: %v", numInt, reflect.TypeOf(numInt)))// 输出// value: 1234567, type: int64// 转成 stringnumStr := result["number"].(json.Number).String()fmt.Println(fmt.Sprintf("value: %v, type: %v", numStr, reflect.TypeOf(numStr)))// 输出// value: 1234567, type: string到此这篇关于Go 语言json.Unmarshal 遇到的小问题(推荐)的文章就介绍到这了,更多相关Go 语言json.Unmarshal内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文整理了一部分我们平时在项目中经常遇到的关于go语言JSON数据与结构体之间相互转换的问题及解决办法。基本的序列化首先我们来看一下Go语言中json.Mars
问题简介Go语言是一个简单却蕴含深意的语言,大家都知道go语言标准库汇总内置了对json文件的处理,非常方便,最近在写一个应用的时候,需要从json文件中载入配
在使用go语言开发过程中,经常需要使用到json包来进行json和struct的互相转换,在使用过程中,遇到了一些需要额外注意的地方,记录如下。整数变浮点数问题
go语言提供了json的编解码包,json字符串作为参数值传输时发现,json.Marshal生成json特殊字符、&会被转义。typeTeststruct{C
Go语言转换JSON数据真是非常的简单。以EasyUI的Demo为例,将/demo/datagrid/datagrid_data1.json拷贝到$GOPATH