
go语言在处理json中的大整数时,默认行为可能导致精度丢失,将其解析为浮点数。本文将深入探讨这一问题,并提供一种专业且可靠的解决方案:利用`json.decoder`的`usenumber()`方法,将数字类型解析为`json.number`字符串,从而有效避免数据类型转换带来的精度问题,确保json数据在go程序中精确地序列化与反序列化。
在使用Go语言的encoding/json包进行JSON数据的序列化(Marshal)和反序列化(Unmarshal)时,如果目标类型是interface{},json包会尝试将JSON中的数字类型自动转换为Go的float64类型。对于不带小数点的整数,尤其是当它们的数值较大时,这种自动转换可能导致数据以科学计数法表示,或者更严重地,由于浮点数的精度限制而丢失原始数值的精确性。
例如,考虑以下JSON字符串:
{
"id": 12423434,
"Name": "Fernando"
}当使用json.Unmarshal将其反序列化到一个interface{}类型的变量,再将其断言为map[string]interface{}时,id字段的值会被解析为float64。随后,如果再次将其序列化回JSON字符串,id字段可能会以浮点数形式(例如1.2423434e+07)出现,从而改变了原始数据的表示形式。
以下是导致此问题的示例代码:
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
// 原始JSON字符串
var b = []byte(`
{
"id": 12423434,
"Name": "Fernando"
}
`)
// 反序列化到 interface{}
var f interface{}
json.Unmarshal(b, &f)
// 断言为 map[string]interface{}
m := f.(map[string]interface{})
// 打印map,可见id已变为浮点数
fmt.Println("反序列化后的map:", m)
// 再次序列化map到JSON
result, _ := json.Marshal(m)
// 打印结果,id以浮点数形式出现
os.Stdout.Write([]byte("再次序列化后的JSON: "))
os.Stdout.Write(result)
fmt.Println()
}运行上述代码,输出结果将类似:
反序列化后的map: map[id:1.2423434e+07 Name:Fernando]
再次序列化后的JSON: {"Name":"Fernando","id":1.2423434e+07}这清楚地表明,id字段的整数值在反序列化过程中被转换为了浮点数。
为了解决这个问题,并确保JSON中的数字(尤其是大整数)在Go程序中能够保持其原始的精确表示,我们可以利用encoding/json包提供的json.Decoder的UseNumber()方法。
UseNumber()方法会改变json.Decoder的默认行为:当遇到JSON中的数字时,它不再将其解析为float64,而是将其解析为json.Number类型。json.Number是一个字符串类型,它存储了数字的原始字符串表示形式。这样,无论数字有多大或多长,它的精确值都不会因浮点数转换而丢失。
Viggle AI Video
Powerful AI-powered animation tool and image-to-video AI generator.
115
查看详情
以下是使用UseNumber()方法的示例代码:
package main
import (
"encoding/json"
"fmt"
"log"
"strings"
)
var data = `{
"id": 12423434,
"Name": "Fernando"
}`
func main() {
// 创建一个 json.Decoder
d := json.NewDecoder(strings.NewReader(data))
// 启用 UseNumber(),使数字解析为 json.Number 类型
d.UseNumber()
var x interface{}
// 使用 Decoder 进行反序列化
if err := d.Decode(&x); err != nil {
log.Fatal(err)
}
// 打印反序列化后的结果,可见id现在是 json.Number 类型(字符串表示)
fmt.Printf("反序列化到 %#v\n", x)
// 再次序列化回JSON
result, err := json.Marshal(x)
if err != nil {
log.Fatal(err)
}
// 打印再次序列化后的JSON,id保持了原始整数形式
fmt.Printf("再次序列化到 %s\n", result)
}运行上述代码,输出结果将是:
反序列化到 map[string]interface {}{"id":"12423434", "Name":"Fernando"}
再次序列化到 {"Name":"Fernando","id":12423434}从输出可以看出,id字段现在被正确地保持为整数形式,没有被转换为浮点数或科学计数法。
json.Number类型是一个string的别名,它在内部存储了JSON中数字的原始文本表示。当UseNumber()被启用后,所有JSON数字都会被解码成json.Number。
优势:
例如,如果你想将json.Number转换为int64,可以这样做:
// 假设 m 是反序列化后的 map[string]interface{}
// 在启用UseNumber()后,x 会被解码为 map[string]interface{}
// 我们可以这样访问其元素:
if decodedMap, ok := x.(map[string]interface{}); ok {
if val, ok := decodedMap["id"].(json.Number); ok {
idInt, err := val.Int64()
if err != nil {
log.Fatalf("无法将id转换为int64: %v", err)
}
fmt.Printf("id (int64): %d\n", idInt)
}
}Go语言的encoding/json包在处理JSON数字时,默认将它们解析为float64,这可能导致大整数的精度问题。通过使用json.Decoder的UseNumber()方法,我们可以将这些数字作为json.Number类型(其原始字符串表示)进行反序列化,从而彻底避免精度丢失。这种方法在处理未知JSON结构或需要精确表示大整数的场景中尤为重要。理解并正确运用UseNumber(),将有助于构建更健壮、数据更精确的Go应用程序。
以上就是解决Go encoding/json 将JSON大数字解析为浮点数的问题的详细内容,更多请关注其它相关文章!
# json
# 创建一个
# 将是
# 我们可以
# 尤其是
# 是一个
# 转换为
# 将其
# 浮点数
# 序列化
# json处理
# 金融
# ai
# go语言
# go
# js
# AI-powered
# 宣城网站优化公司有哪些
# 石家庄数字营销推广公司
# seo560
# 阜阳网站优化哪家专业
# 网络营销推广方向有哪些
# seo排名第一的工具seo博客
# 电子商务里的seo
# 营销推广全网整合营销
# 单位网站建设哪个好
# 西乡怎么找网站优化
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
抖音怎么解除第三方绑定_抖音解除第三方平台绑定方法介绍
CDR如何复制交互式填充色
Excel怎么用XLOOKUP函数实现双向查找_ExcelXLOOKUP替代VLOOKUP+HLOOKUP的高级用法
悟空浏览器网页版在线工具 悟空浏览器网页版在线平台入口
西瓜视频怎么查看访客记录_西瓜视频访客记录查看方法
2025考研成绩查询时间入口分享
漫蛙漫画直连入口 _ manwa官方备用入口实时检测
热血江湖归来医师加点攻略
Excel如何设置动态下拉菜单_Excel表格下拉选项快速方法
优化Google Charts Gauge:在数据库无数据时显示默认值
鸣潮历史学家灯塔位置一览
《磁力猫》最好用的磁官网
Windows自带的便笺数据如何备份_防止数据丢失的便利贴迁移教程【干货】
Safari浏览器自动填表功能失效怎么办 Safari表单管理修复
菜鸟裹裹怎样获得取件码_菜鸟裹裹获得取件码步骤
《盗墓笔记手游》技能介绍
XPath动态元素定位:如何精准选择文本内容变化的元素
苹果如何下载nanobanana
智慧团建活动报名入口 智慧团建活动报名入口手机端官网
路由器DNS怎么设置最快 优化DNS提升上网速度教程
键盘声音异常怎么回事_键盘异响怎么处理
Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法
Win10怎么设置快速启动 Win10开启快速启动设置方法
Flexbox布局:实现粘性导航与底部页脚的完美结合
荣耀Magic6 Pro拍照成像偏暗_荣耀Magic6 Pro夜景优化
申通快件单号查询平台 申通包裹物流动态跟踪
Mac如何开启画中画模式_Mac Safari浏览器视频画中画功能
php如何实现多域名共享session_php存储session到redis与跨域读取配置
苹果手机缓存怎么清除_苹果手机缓存如何清除iphone各版本操作步骤
J*aScript包管理器_Npm与Yarn对比
VS Code源代码管理(SCM)视图的进阶使用技巧
《偃武》甘宁技能详解
在PHP环境中正确加载HTML资源:CSS样式与图片路径指南
疯狂小鸟微信小游戏入口 疯狂小鸟网页版秒玩
电脑“无法访问指定设备、路径或文件”怎么办?五种权限设置方法
抖音网页版地址直接进入_抖音网页版在线观看入口
J*a中导出MySQL表为SQL脚本的两种方法
firefox火狐浏览器最新官网主页_ firefox火狐浏览器平台入口直达官方链接
PHP与SQL实践:高效实现数据复制与特定列值修改
铁路12306买票怎么选双人铺 铁路12306卧铺分配规则说明
斯宾塞称XGP云游戏“蒸蒸日上”:正在构建一个游戏从未如此唾手可得的未来
QQ邮箱手机版网页版 QQ邮箱登录入口地址
yy漫画登录页面官方入口_yy漫画在线阅读网址入口
PyEZ 配置提交中 RpcTimeoutError 的健壮性处理策略
抖音如何解除|直播|权限绑定_抖音关闭并解绑|直播|功能的方法
《腾讯相册管家》注销账号方法
猫眼电影app如何参与官方的抽奖活动_猫眼电影官方抽奖参与方法
谷歌浏览器如何查找和删除恶意软件 谷歌浏览器内置安全清理工具使用教程
Go语言反射机制:如何访问被嵌入结构体遮蔽的方法
vivo手机视频通话美颜怎么设置_vivo视频通话美颜开启方法
2025-11-29
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。