JSON 转 Go 结构体转换器

粘贴一个 JSON 对象(或 JSON 数组),自动生成对应的 Go struct 定义及 json 标签。

从 JSON 生成 Go 结构体

要在 Go 里接收 API 响应,就得写出与该 JSON 对应的结构体及其 json 标签。字段只有几个时并不费事,**可一旦嵌套加深,边想类型名边顺着层级走,本身就成了负担。** 本工具只需您贴入 JSON,便会连同嵌套结构一并生成整套定义。

**不过请记住,产出的是「由一份样本推断出的类型」。** 样本中未出现的键自然不会有,而值为 `null` 的字段会变成 `interface{}`,因为 Go 并无可对应的可空基本类型。若数组的元素全是对象,则各元素的键会合并为一个结构体,**只在部分元素中出现的键会被标上 `omitempty`。** 要把输出变成可用于生产的结构体,前提是您会拿这些推断去对照真正的 API 规格并加以订正。

转换的步骤

  1. 贴入 JSON 对象或数组皆可,API 响应可原样贴入。
  2. 给根类型命名 初始为 `Root`。**嵌套类型的名称由各属性名转为帕斯卡命名法自动得出。**
  3. 查看生成的结构体 定义会按层级顺序排列,json 标签一并就位。
  4. 复制出来再整理 先过一遍 `gofmt`,再依真实规格订正变成 `interface{}` 的地方,以及该用指针的地方。

用好本工具的小技巧

  • 当数组的所有元素都是对象时,会合并各元素的键生成一个 struct。仅存在于部分元素中的键会自动加上 `omitempty` 标签。
  • 根类型名称默认是 "Root",可以改成你喜欢的名字。嵌套对象的 struct 名称会根据属性名自动转换为 PascalCase 生成。
  • 由于 Go 没有原生的可空基本类型,JSON 的 null 会被转换为 `interface{}`。如需更严格的处理,可以考虑改用指针类型。
  • 生成结果只是简单对齐列宽的草稿,粘贴后通过 `gofmt` 处理即可对齐到项目的标准风格。
  • 直接粘贴 API 响应的示例 JSON,即可快速得到 Go 中响应结构体的初稿。

这些场景会用到

着手写 API 客户端时

把文档里的示例响应贴上,马上就有一份接收用结构体的初稿。

读取配置文件时

设置以 JSON 保存时,可把其结构直接誊写成类型。

读懂第三方规格时

**层层嵌套的 JSON,一旦摊开成结构体便容易把握得多。**

准备测试夹具时

先由真实响应推出类型,写模拟数据时便少了张冠李戴之虞。

Go 类型映射的术语

结构体
Go 中把若干字段聚在一起的类型,对应 JSON 里的对象。
json 标签
写在字段之后、形如 `json:"user_id"` 的注解,**它告诉编码器 Go 的字段名与 JSON 的键如何对齐。**
omitempty
json 标签中的一个选项,**当值为零值时把该字段从输出中略去。** 它并不表示该字段可为空,这一分别值得记牢。
interface{}
可接纳任意值的类型。JSON 的 null 与类型多变的字段会落到这里,**因而成了生成后需回头查看之处的标记。**
帕斯卡命名法
每个单词首字母大写的写法,如 `UserId`。在 Go 中**这个开头的大写还兼有从包中导出的含义。**
指针类型
写作 `*string` 的类型。当「没有值」必须与「空字符串」区分开来时,便要用它。

常见问题

手工从示例响应编写 struct 既耗时又容易出错,尤其在嵌套层级较深时,容易写错字段名转换或漏写 json 标签。自动生成可以避免这些错误,大幅缩短开发时间。

JSON 键(snake_case 或 camelCase)会被转换为首字母大写的 PascalCase,成为 Go 中可导出的字段名。原始的 JSON 键会原样保留在 json 标签(`json:"原始键"`)中,因此编码解码不受影响。

null 值会被输出为 `interface{}` 类型。仅在数组部分元素中出现的键会自动带上 `omitempty` 标签,但 Go 类型本身只会取零值,如需区分"缺失"与"零值",可以考虑改用指针类型。

含有小数点的 JSON 数值会被判断为 `float64`,不含小数点的则判断为 `int`。由于 JSON 的数值表示只保留位数信息,对于需要 `int64` 的超大数值,请生成后手动调整。

由于 Go 没有联合类型,同一个键在不同元素中类型不一致时会回退为 `interface{}`,需要在运行时用类型断言来判断实际的值类型。
工具君

闲话 ― Go 中 struct 与 json 标签的设计

Go 是一门静态类型语言,在处理 JSON 时,标准库的 `encoding/json` 包依赖 struct 字段与 json 标签之间的对应关系来完成编码和解码。手工为外部 API 的响应结构编写 struct 是一项随着字段增多而愈发繁琐的重复劳动,这在许多 Go 项目中反复出现。

这款工具通过解析示例 JSON 的结构,自动生成对应的 struct 定义和 json 标签,从而减轻这类重复工作。同类工具中,支持转换为多种语言类型的 quicktype 颇为知名;但如果只是想粘贴一份示例 API 响应、快速得到一个 Go struct,专注单一功能的工具也自有其便利之处。

由于 Go 没有让 struct 字段变为"可选"的语言特性,对于 JSON 中可能缺失的字段,常见做法是在 json 标签中加上 `omitempty`,或改用指针类型(如 `*string`)来区分零值与"值不存在"。生成的 struct 终究只是根据结构做出的机械推断,将可空性判断和 API 未来变化纳入设计,应当对照实际的接口文档手动调整,这是实践中的通行做法。