JSON 转 Go:转换差异、边界与常见坑

在线 JSON 转 Go:生成带 json tag 的 struct,并明确 omitempty 取舍;大整数一律提示 float64 精度风险,避免线上出现尾部数字被改写。

生成 Go struct 时,字段必须导出(首字母大写)才能被 encoding/json 序列化,因此属性名与 json tag 是成对出现的。数字统一落成 float64 是 Go 解码的固有行为,业务上需要整数就必须手工改成 int64。

两种格式的差异对照

维度JSONGo struct
字段可见性无此概念小写字段不被序列化,必须首字母大写
键名映射键名任意用 json:"snake_case" tag 显式映射
数字类型统一 numberfloat64 / int / int64 需人工选择
null 处理null 值指针、sql.NullString 或 omitempty 表达
缺失字段键不存在零值(0、""、nil 语义不同)
嵌套结构嵌套对象嵌套 struct 或 map[string]interface{}
数组原生数组切片 []T,元素类型必须一致
运行时开销解析轻量反射解码较慢,可用代码生成提速

边界条件

  • JSON 字段可能缺失时,用 omitempty 会让零值与"未设置"无法区分,需要指针类型来表达"存在且为零"。
  • 空数组在 Go 里解码为 nil 切片,序列化回去变成 null 而不是 [],接口契约可能因此变化。
  • 键名含连字符或点号无法直接作为 tag 之外的标识符,必须依靠 json:"..." 映射。
  • 超长整数(订单号)用 float64 会失真,必须改为 string 或 int64。

常见坑

  • 手工把小写字段名当成"符合 Go 风格",结果序列化输出空对象,且没有任何报错。
  • 金额用 float64,累加后出现分位误差,对账时才发现。
  • 空数组往返后变成 null,前端按数组遍历直接抛异常。
  • omitempty 到处乱用,把"显式设为 0"也一起省略,业务语义丢失。

相关工具

常见问题

怎么把 Go 再转回 JSON?

使用同工具的交换方向功能,或本站对应的「Go 转 JSON」页面,两者都本地运行、数据不上传,可完成往返转换与校验。

JSON 和 Go 哪个更适合人类阅读?

这取决于场景:Go 通常更偏向程序解析与接口传输式的可读形态,而 JSON 更利于程序解析与接口传输式的程序消费;需要人工编辑时优先选可读性更高的那一侧。

生成的 struct 字段为什么都是首字母大写?

Go 只有导出的字段(首字母大写)才能被 encoding/json 序列化,小写字段会被静默忽略(输出空对象且不报错)。所以生成结果默认用大写属性名 + json tag 映射原始键名,这是 Go 的惯例而不是工具偏好。

数字为什么都生成 float64?

JSON 的数字没有整数/浮点之分,Go 解码到 interface{} 时统一给 float64。若你的整数业务字段(如自增 ID、金额分)需要整数,必须手工改成 int/int64;金额建议用 int64 存最小单位或 string,避免浮点误差。