Golang:JSON和int64、interface的那些事儿

本文介绍了Golang中JSON反序列化时可能遇到的精度丢失问题,特别是针对int64类型。由于JSON中数字默认解析为float64,可能导致精度丢失。解决方法是将数据解析到interface{},并使用json.Number存储原始字符串。在比较两个由JSON反序列化的map时,需要注意处理number类型的值,避免直接用int64进行比较,而应转换为字符串进行判断。
摘要由CSDN通过智能技术生成

先来看一下 : JSON number的那些事


golang 数据类型和json类型对照关系表:

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中没有int64类型的,反序列化的时候,如果直接用json.Unmarshal 可能会精度丢失
可以参考这篇文章:json 反序列化数字精度丢失

原理
解析 JSON 的时候其实是对 JSON 串的遍历,其实所有遍历出来的值都是[]byte类型,然后根据识别目标解析对象字段类型,或者识别[]byte数据的内容转换格式。

比如,如果数据被解析到int上,把[]byte转换为int;
如果被解析到interface{}上,就只能通过[]byte的类型来转换了,
而且数字会被统一处理成float64,这个有个问题,就是会丢精度。
而通过Number解析时,值会被直接保存为字符串类型

正确做法:

func DecodeMyStruct(jsonStr string) (*MyStruct, error) {
   
	var regular *MyStruct
	decoder := jsoniter.NewDecoder(strings.NewReader(jsonStr))
	//使用UseNumber()可以使得json中的大整数转换时,不会转换成浮点数float64,但是要用decoder不能用json.Marshal
	decoder.UseNumber() 
	err := decoder.Decode(&regular)
	if err != nil {
   
		return nil, err
	}
	return &regular, nil
}

其中 MyStruct是我们需要反序列化的类型,可以是struct,slice, map等等.

如果不知道应该反序列化成啥类型,可以是map[string]interface{},用的时候可以配合断言使用,

比如下面一种场景:需要对比两个json反序列化成map[string]interface{}的结构,
判断:filterAttrMap 是不是包含 conditionMap的所有键值对。

func CompareRecursiveV2(ctx context.Context, filterAttrMap, conditionMap map[string]interface{
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值