JSON 转 Go Struct

从 JSON 即时生成带 json tag 的 Go struct,支持嵌套对象、数组、指针可空字段和 omitempty 标签。免费,在浏览器中运行。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
留空时使用 RootObject。修改名称后,点击「生成 Go Struct」应用。
立即按当前 JSON 和根名生成,也可按 Ctrl/⌘+Enter 生成。
用含嵌套对象、数组和 null 的示例替换 JSON,并按当前设置立即生成。
清空 JSON、输出和状态,保留根名。在工具内按 Ctrl/⌘+L 还会清空根名。
输入合法 JSON,不能带注释或末尾逗号。停止输入 300 毫秒后自动生成;JSON 无效时会清空输出并显示错误。
Go 输出
复制当前显示的完整 Go 输出。输出为空时不复制。

输入 JSON 或载入示例以生成 Go。

示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

类型映射

  • null → interface{}
  • 字符串 → string
  • 整数 → int
  • 浮点数 → float64
  • 布尔值 → bool
  • 数组 → []T
  • 可空/可选 → 指针(*T)
  • 嵌套对象 → 独立的命名 struct

示例:API 响应

{
  "user": {
    "id": 42,
    "name": "Alice",
    "email": "alice@example.com",
    "is_active": true,
    "roles": ["admin", "editor"],
    "address": { "city": "New York", "country": "US", "zip_code": "10001" },
    "last_login": null
  }
}

生成:

type RootObject struct {
	User User `json:"user"`
}

type User struct {
	Id int `json:"id"`
	Name string `json:"name"`
	Email string `json:"email"`
	IsActive bool `json:"is_active"`
	Roles []string `json:"roles"`
	Address Address `json:"address"`
	LastLogin interface{} `json:"last_login"`
}

type Address struct {
	City string `json:"city"`
	Country string `json:"country"`
	ZipCode string `json:"zip_code"`
}

snake_case 键名转成 CamelCase 字段名,json 标签保留原始键名,encoding/json 编解码时两边都能对上。字段没有对齐,用 gofmt(或保存时自动格式化的编辑器)整理即可。用标准库解码:

var root RootObject
if err := json.Unmarshal(data, &root); err != nil {
	log.Fatal(err)
}
fmt.Println(root.User.Name) // Alice

示例:顶层是数组

[{"sku": "A1", "qty": 2}, {"sku": "B2", "note": "gift"}]

生成:

type RootObject struct {
	Sku string `json:"sku"`
	Qty *int `json:"qty,omitempty"`
	Note *string `json:"note,omitempty"`
}

顶层是数组时,结构体描述的是单个元素,解码到 []RootObject。在部分元素中缺失的键会变成带 omitempty 的指针。

示例:同名键、小数与数字开头的键

{
  "order": { "id": "A-1001", "total": 19.0, "meta": { "createdBy": "alice", "source": "web" } },
  "payment": { "status": "paid", "meta": { "provider": "stripe", "fee": 0.3 } },
  "2fa": true
}

生成

type RootObject struct {
	Order Order `json:"order"`
	Payment Payment `json:"payment"`
	X2fa bool `json:"2fa"`
}

type Order struct {
	Id string `json:"id"`
	Total float64 `json:"total"`
	Meta Meta `json:"meta"`
}

type Meta struct {
	CreatedBy string `json:"createdBy"`
	Source string `json:"source"`
}

type Payment struct {
	Status string `json:"status"`
	Meta PaymentMeta `json:"meta"`
}

type PaymentMeta struct {
	Provider string `json:"provider"`
	Fee float64 `json:"fee"`
}

payment.meta 的字段与 order.meta 不同,所以单独生成结构体,名称前加父级:PaymentMeta;字段相同时两者共用 Meta。19.0 带小数点,所以 total 是 float64:encoding/json 拒绝把 19.0 解码到 int 字段。工具通过浏览器的 JSON 源文本访问(Chrome 114+、Firefox 135+、Safari 18.4+)读取数字的原始写法;不支持的浏览器只能看到 19,仍生成 int。键 2fa 不能作为导出名称的开头,所以字段名是 X2fa,标签保留 2fa。

生成后需要修改的地方

  • null 生成 interface{}。对照 API 文档后改成实际类型的指针,如 *string、*time.Time。
  • 不带 . 或指数的数字生成 int,19.0、1e3 生成 float64;同一数组或同一键里整数与小数混合时生成 float64。样本里碰巧都是整数的字段(如价格)仍是 int,请核对。在 64 位平台上 int 是 64 位。
  • [] 以及其他元素类型混杂的数组生成 []interface{}。
  • 字段名不会按 Go 的缩写惯例调整:id 变成 Id、url 变成 Url,而 Go Code Review Comments 建议写成 ID、URL。无论哪种写法,json 标签都能保证解码正确。
  • 字段名开头不是大写字母时(2fa、名前)加前缀 X(X2fa);两个键生成同一字段名时(user_id、userId)加数字(UserId2)。空键以及含结构体标签无法容纳的字符(如 "、,)的键改为写在注释里,因为 encoding/json 无法通过标签映射它们。
  • PaymentMeta、Meta2 这类名称由 JSON 键名生成,可按业务含义改名。
  • 只生成 json 标签,gorm、bson、validate 等标签需要自己加。

限制

  • 输入必须是合法 JSON,报错信息会给出位置,例如末尾多一个逗号时显示 Expected double-quoted property name in JSON at position 8。
  • 类型只来自你粘贴的样本。

FAQ

这个工具生成什么?

生成带有 json struct tag 的 Go struct 类型声明。每个嵌套 JSON 对象都会成为独立的命名 struct,数组字段变为切片([]T)。

如何处理可空字段?

样本中只出现 null 的键生成 interface{},因为从样本看不出它的类型。在对象数组里,部分元素为 null、其他元素有值的键生成该类型的指针(如 *string);部分元素缺少的键生成指针(切片仍是切片),并在 json tag 里加 ,omitempty。

为什么使用指针类型?

在 Go 中,指针是表示可选或可空值的惯用方式。*string 可以为 nil(缺失/空),而 string 不能。

会生成哪些 json tag?

每个字段都带 json tag,内容是原始 JSON 键名,所以字段改成 Go 的导出名(大写开头)后,snake_case 或 camelCase 的键仍能对上。数组中部分元素缺少的键还会加 ,omitempty。空键以及含双引号、逗号等 json tag 无法容纳的字符的键,写成注释而不是字段。只生成 json tag。

数据会发送到服务器吗?

不会。结构体在浏览器标签页里生成,输入的 JSON 和根结构体名称不会发送到服务器,也不会保存到浏览器存储。编辑完输入框、焦点移开时,或点击「生成 Go Struct」或载入示例时,页面的统计只记录一次使用事件(工具名和动作 generate),不包含 JSON 或代码。