测试阶段发现json转int64后部分精度有丢失,造成数据不一致,程序异常,提供错误案例以及如何正确使用
var configDetailList []interface{}
configStr, err := tccClient.Get(ctx, key)
if err != nil {
logs.CtxError(ctx, "get [config]:%s is err,err:%s", key, err)
return configDetailList, nil
err = json.Unmarshal([]byte(configStr), &configDetailList)
if err != nil {
logs.CtxError(ctx, "json Unmarshal is err,serviceMeta:%s,err:%s", key, err)
return configDetailList, uerr.SystemInternalError.WithMessage("tcc json Unmarshal is err")
实际结果:
"key":"tenant_crowd_id_list",
"field_meta_list":[
"key":"crowd_id",
"type":"int64",
"name":"圈人包id",
"default_value":"1",
"description":"圈人包id",
"tenant_value":"71019664740587300000"
"name":"租户对应圈人包id list",
"description":"租户对应圈人包id list"
预期结果 tenant_value :710196647405873023890
实际结果和预期结果相比精度损失几位,使得目标结果不正确造成程序异常
当数据结构未知,使用 map[string]interface{} 来接收反序列化结果时,如果数字的位数大于 6 位,都会变成科学计数法,用到的地方都会受到影响。
是因为当 JSON 中存在一个比较大的数字时,它会被解析成 float64 类型,就有可能会出现科学计数法的形式。
所以此问题在struct类型的时候不会出现,仅针对于[]interface{}
可以使用Decode代替unmarshall来解决
var configDetailList []interface{}
d := json.NewDecoder(bytes.NewReader([]byte(configStr)))
d.SetNumberType(json.UnmarshalIntOrFloat) //关键
err = d.Decode(&configDetailList)
if err != nil {
logs.CtxError(ctx, "json Unmarshal is err,serviceMeta:%s,err:%s", key, err)
return configDetailList, uerr.SystemInternalError.WithMessage("json Unmarshal is err")
if configDetailList == nil {
configDetailList = make([]interface{}, 0)
return configDetailList, nil
d.SetNumberType()可以设置三种类型,可以根据自己的需要来选择适合业务的数据类型
const (
// unmarshal a JSON number into an interface{} as a float64
UnmarshalFloat NumberUnmarshalType = iota
// unmarshal a JSON number into an interface{} as a `json.Number`
UnmarshalJSONNumber
// unmarshal a JSON number into an interface{} as a int64
// if value is an integer otherwise float64
UnmarshalIntOrFloat
Golang的使用上还是个小小菜鸟,也懈怠很久了,要好好开始努力了,停止摆烂,要努力发光。虽然转了语言要放正自己的态度,既然做了,就要做好,停止半吊子,做积极向上的好青年!!!
在一次fabric chaincode的开发过程中,计划使用leveldb数据库,所以存储的数据都是key,value类型的数据。value 是一个json 类型的字符串。由于希望项目不用每张表都建立一个具体的结构,这样项目的复用性也可以更好的提高。所以最后决定直接通过json 字符串解析成map 类型的结构进行开发。下面详细介绍json 在golang 里面的简单特性。
一、Json和struct互换
(1)Json转struct例子:
package main
import (
encoding/json
type People st
QJsonObject中存储的数据结构为long long格式 或者 qint64位格式时,其实是作为double类型存储在QjsonValue里的,所以使用如下方式可将其转换为qint64类型,提供一个思路,代码具体使用场景视情况而定。
qint64 getLongData(QJsonObject json, QString key)
return QString::number(json.value(key).toDouble(), 'f', 0).toLongLong();
根据JSON规范,数字可以表示为整数或浮点数,而Go语言中的float64类型可以容纳JSON中的所有数字范围。为了支持更广泛的数字类型,Go的JSON解析器默认将JSON中的数字解析为float64类型。在Go语言中,使用json.Unmarshal()函数将JSON数据反序列化为Go结构时,整数(int)类型可能会被转换为float64类型的原因是JSON中的数字默认为浮点数。因此可以使用cast.ToInt()再转成int。
type(np.float64(0).item()) #
type(np.uint32(0).item()) #
# examples using np.asscalar(a)
type(np.a
json 简介jsON(JavaScriptObject Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgramming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于 C语言...
golang int64 json.Unmarshal精度丢失问题并解决问题描述问题原因解决方法decode+UseNumber()
近期项目遇到一个小问题,在postman测试我在上传数据溯源的时候,一个id类型为int64格式的查询返回和我查询参数id竟然后两位不同,例如:386170898069065728 变成 386170898069065700,也就是精度出现丢失,在进行debug之后将问题锁定在了json.Unmarshal方法上,因其他string类型的数据都正常按照上传的内容返回
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
json中没有int64类型的,反序列化的时候,如果直接用json.Unmars
JSON(Javascript Object Notation)是一种轻量级的数据交换语言,以文字为基础,具有自我描述性且易于让人阅读。尽管JSON是JavaScript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。JSON与XML最大的不同在于XML是一个完整的标记语言,而JSON不是。JSON由于比XML更小、更快,更易解析,以及浏览器的內建快速解析支持,...
在Pandas中,当你使用to_json()函数时,该函数会将DataFrame中的所有数据类型转换为可以在JSON中表示的数据类型。要解决这个问题,你需要将这个int64类型的对象转换为可以在JSON中表示的数据类型。在Python中,你可以使用int()函数将这个对象转换为一个普通的整数,或者使用str()函数将其转换为一个字符串。这个错误通常意味着你试图将一个Python对象转换为JSON,但是这个对象不能被序列化为JSON。在你的情况下,错误发生在尝试将一个int64类型的对象转换为JSON时。
我负责的需求是这样,存储文件绝对路径和文件大小到json字符串。开发过程中,未意识到文件可能大于int的最大值,所以埋下了隐患。今天被测试提了个bug。主要原因是QJsonValue的toInt()返回的是4字节的int类型,拿来存一个大于有符号四字节整数的值会溢出。这种边界值界定不明确导致bug的情况还是比较常见,做个总结分享帮助大家避坑。此外就是csdn上对于这块的教程属实是又少又粗略。1.QJsonValue存储整数是按照double类型存储的,即使是1这么一个很小的数。
JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效的提升网络传输效率。关于JSON的更多解释,请参看JSON官网。