Go语言JSON转换陷阱:整数转浮点数
7 浏览量
更新于2024-08-31
收藏 199KB PDF 举报
"Go语言中进行JSON转换时可能会遇到的问题及解决方案"
在使用Go语言进行开发时,JSON转换是常见的操作,特别是在数据交互和序列化过程中。Go的标准库`encoding/json`提供了方便的API用于JSON与结构体间的转换。然而,在实际应用中,我们可能会遇到一些意料之外的问题,本文将探讨其中的一个主要问题:整数和浮点数转换不准确。
首先,我们来看一个例子,定义了一个`Person`结构体,包含`Age`(int64)和`Weight`(float64)字段。通过`json.Marshal`将`Person`结构体转换为JSON字符串,再使用`json.Unmarshal`将JSON解析为`map[string]interface{}`。问题在于,当将解析后的JSON对象强制转换为`map[string]interface{}`后,原本的`Age`(整数)和`Weight`(浮点数)都被转换成了`float64`类型。
```go
type Person struct {
Name string
Age int64
Weight float64
}
func main() {
person := Person{
Name: "WangWu",
Age: 30,
Weight: 150.07,
}
jsonBytes, _ := json.Marshal(person)
var personFromJSON interface{}
json.Unmarshal(jsonBytes, &personFromJSON)
r := personFromJSON.(map[string]interface{})
fmt.Println(reflect.TypeOf(r["Age"]).Name()) // float64
fmt.Println(reflect.TypeOf(r["Weight"]).Name()) // float64
}
```
这个问题的原因在于JSON规范中没有区分整数和浮点数,所有的数值都被视为同一类型,即浮点数。因此,Go的`json.Unmarshal`函数会将所有数字转换为最接近的浮点类型,即`float64`。这可能造成数据精度丢失,尤其是对于大整数而言。
为了解决这个问题,`encoding/json`包提供了一种方式,可以保留原始的整数类型,即使用`json.Number`。`json.Number`是一个字符串类型,它允许JSON的数字在Go中保持原始的文本形式,直到需要进行数值计算时才进行转换。
```go
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age json.Number `json:"age"`
Weight float64 `json:"weight"`
}
func main() {
person := Person{
Name: "WangWu",
Age: json.Number("30"),
Weight: 150.07,
}
jsonBytes, _ := json.Marshal(person)
var personFromJSON map[string]json.RawMessage
json.Unmarshal(jsonBytes, &personFromJSON)
age, _ := personFromJSON["age"].(json.Number).Int64()
fmt.Println(age) // 30 (int64类型)
}
```
通过使用`json.Number`,我们可以确保`Age`字段在解析后仍保持其原始的整数形式,并且可以根据需要转换为适当的整数类型,而不会丢失精度。这样,我们就成功地避免了整数被错误地转换为浮点数的问题。
总结来说,Go语言在进行JSON转换时需要注意数字类型的处理。默认情况下,`json.Unmarshal`会将所有数字转换为`float64`,可能导致精度问题。通过使用`json.Number`,我们可以保留原始的数字格式,从而确保数据的准确性。在处理JSON与结构体之间的转换时,理解这些细节是至关重要的,有助于提高代码的健壮性和数据的完整性。
2019-08-14 上传
2021-06-12 上传
2015-12-19 上传
2023-05-25 上传
2023-09-06 上传
2023-07-27 上传
2023-09-01 上传
2023-04-25 上传
2023-03-29 上传
weixin_38716563
- 粉丝: 5
- 资源: 871
最新资源
- JHU荣誉单变量微积分课程教案介绍
- Naruto爱好者必备CLI测试应用
- Android应用显示Ignaz-Taschner-Gymnasium取消课程概览
- ASP学生信息档案管理系统毕业设计及完整源码
- Java商城源码解析:酒店管理系统快速开发指南
- 构建可解析文本框:.NET 3.5中实现文本解析与验证
- Java语言打造任天堂红白机模拟器—nes4j解析
- 基于Hadoop和Hive的网络流量分析工具介绍
- Unity实现帝国象棋:从游戏到复刻
- WordPress文档嵌入插件:无需浏览器插件即可上传和显示文档
- Android开源项目精选:优秀项目篇
- 黑色设计商务酷站模板 - 网站构建新选择
- Rollup插件去除JS文件横幅:横扫许可证头
- AngularDart中Hammock服务的使用与REST API集成
- 开源AVR编程器:高效、低成本的微控制器编程解决方案
- Anya Keller 图片组合的开发部署记录