相关文章推荐
酷酷的煎鸡蛋  ·  Golang WebSocket Ping ...·  2 月前    · 
想旅行的小笼包  ·  vue.js - ...·  1 年前    · 

测试阶段发现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 类型的结构进行开发。下面详细介绍jsongolang 里面的简单特性。 一、Json和struct互换 (1)Jsonstruct例子: 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官网。