JSON转Go结构体

从JSON生成Go结构体

加载示例
根结构体名称:

JSON输入

Go输出

本地运行 · 粘贴密钥安全无忧
Go结构体将显示在这里…

什么是JSON转Go结构体转换?

JSON转Go结构体转换是指将原始JSON数据转换为与Go标准库encoding/json包配合使用的类型定义。Go是静态类型语言,每个JSON字段都需要一个对应的结构体字段,包含正确的类型以及告知序列化器如何映射JSON键的结构体标签。对于大型或深度嵌套的API响应,手动编写这些定义既耗时又容易出错。

自Go 1.0起纳入规范的encoding/json包使用反射将JSON键与导出的结构体字段进行匹配。默认情况下匹配不区分大小写,但显式json结构体标签是标准做法,因为它消除了歧义,并允许Go使用PascalCase命名规范,同时保持JSON为camelCase或snake_case。转换器自动完成这一过程:读取JSON,从值推断Go类型,并输出带有正确标签的结构体定义。

Go的类型系统与JSON能够清晰对应。字符串映射为string,布尔值映射为bool,整数映射为int,浮点数映射为float64。嵌套JSON对象映射为独立的命名结构体,数组映射为切片。唯一的差距在于null:Go没有通用的可空类型,因此null值通常映射为指针类型(*string、*int)或interface{}。生成器在毫秒内处理所有这些情况。

为什么使用JSON转Go生成器?

手动根据JSON定义Go结构体意味着要数清括号、猜测类型,以及每次API变更时重写标签。生成器消除了这些摩擦。

即时生成类型
粘贴JSON,不到一秒即可获得正确的Go结构体定义。无需手动输入字段类型,不会遗漏标签,也没有对齐烦恼。
🔒
隐私优先处理
转换完全在浏览器中运行,JSON数据不会离开您的设备。API密钥、令牌和用户数据始终保持私密。
🏷️
正确的结构体标签
每个生成的字段都包含json结构体标签,将Go字段名映射到原始JSON键名,防止json.Unmarshal时发生静默不匹配。
📦
无需安装或注册
打开页面,粘贴JSON即可使用。无需Go工具链,无需安装CLI工具,无需创建账号。

JSON转Go结构体使用场景

REST API客户端开发
为第三方REST API生成请求和响应结构体。从API文档粘贴示例JSON,即可获得可直接用于http.Client和json.NewDecoder的类型。
gRPC网关模型
当Go服务同时暴露gRPC和REST端点时,需要与JSON载荷匹配的Go结构体。将JSON结构转换为与protobuf定义匹配的结构体。
DevOps配置解析
将JSON配置文件(Terraform输出、Kubernetes清单、CI/CD流水线配置)解析为带类型的Go结构体,用于自定义工具和自动化脚本。
数据管道处理
为来自消息队列(Kafka、RabbitMQ、SQS)或数据湖中的JSON记录构建Go结构体。带类型的结构体在编译时而非运行时捕获schema变更。
测试夹具设置
将JSON测试夹具转换为Go结构体,用于表驱动测试。相比原始map[string]interface{}断言,带类型的夹具使测试失败更易诊断。
学习Go类型系统
来自动态语言的学习者和开发者可以粘贴熟悉的JSON,查看Go如何用显式类型、指针和结构体标签表示相同的数据。

JSON到Go类型映射参考

encoding/json包在将JSON值映射到Go类型时遵循特定规则。下表展示默认映射和常见替代方案。「默认」列是大多数生成器的输出。「替代」列展示可根据需求选择的类型,例如对大型ID使用int64,对可空字段使用指针类型。

JSON类型示例默认替代
string"hello"stringstring
number (integer)42intint64
number (float)3.14float64float64
booleantrueboolbool
nullnullinterface{}*string / *int
object{"k": "v"}structstruct
array of strings["a", "b"][]string[]string
array of objects[{"id": 1}][]Item[]Item
mixed array[1, "a"][]interface{}[]interface{}

Go JSON结构体标签参考

结构体标签控制encoding/json如何序列化和反序列化字段。json标签是最常用的,但可以与其他标签(db、yaml、xml)组合使用于同一字段。标签语法是字段类型后面由反引号分隔的字符串。以下是encoding/json支持的json标签选项。

标签行为使用场景
json:"name"Maps struct field to JSON key "name"Always generated
json:"name,omitempty"Omits field from output if zero valueOptional fields
json:"-"Field is never serialized or deserializedInternal fields
json:"name,string"Encodes int/bool as JSON stringString-encoded numbers

json.Unmarshal与json.NewDecoder的区别

Go提供两种解码JSON的方式:json.Unmarshal处理字节切片,json.NewDecoder处理io.Reader流。两者使用相同的结构体标签规则,但适用场景不同。

json.Unmarshal
接受[]byte并填充结构体。最适合已完全加载到内存中的JSON:通过io.ReadAll读取的HTTP响应体、文件内容或测试夹具。若JSON格式错误或类型不匹配则返回错误。
json.NewDecoder
包装io.Reader并在数据到达时解码JSON令牌。最适合流式来源:直接读取的HTTP响应体、换行分隔的JSON(NDJSON)日志,或不希望完全加载到内存中的大文件。对于多对象流,配合More()在循环中调用Decode()。

代码示例

以下示例展示如何在真实程序中使用从JSON生成的Go结构体,以及如何从其他语言生成这些结构体。Go示例使用标准库中的encoding/json。

Go (json.Unmarshal)
package main

import (
	"encoding/json"
	"fmt"
)

type User struct {
	ID       int      `json:"id"`
	Name     string   `json:"name"`
	Email    string   `json:"email"`
	IsActive bool     `json:"is_active"`
	Tags     []string `json:"tags"`
}

func main() {
	data := []byte(`{"id":1,"name":"Alice","email":"alice@example.com","is_active":true,"tags":["admin","editor"]}`)

	var user User
	if err := json.Unmarshal(data, &user); err != nil {
		panic(err)
	}
	fmt.Println(user.Name)  // → Alice
	fmt.Println(user.Tags)  // → [admin editor]
}
JavaScript (fetch + type reference)
// JSON response from API — this is the shape you'd convert to Go:
const res = await fetch("https://api.example.com/users/1");
const user = await res.json();
// user → { "id": 1, "name": "Alice", "email": "alice@example.com" }

// Equivalent Go struct:
// type User struct {
//     ID    int    `json:"id"`
//     Name  string `json:"name"`
//     Email string `json:"email"`
// }
Python (generate Go structs from JSON)
import json

def json_to_go(data: dict, name: str = "Root") -> str:
    lines = [f"type {name} struct {{"]
    type_map = {str: "string", int: "int", float: "float64", bool: "bool"}

    for key, value in data.items():
        go_type = type_map.get(type(value), "interface{}")
        field = key.title().replace("_", "")  # snake_case → PascalCase
        lines.append(f'\t{field} {go_type} `json:"{key}"`')
    lines.append("}")
    return "\n".join(lines)

data = json.loads('{"user_name": "Alice", "age": 30, "verified": true}')
print(json_to_go(data))
# type Root struct {
#     UserName string `json:"user_name"`
#     Age      int    `json:"age"`
#     Verified bool   `json:"verified"`
# }
Go (json.Decoder for streams)
package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type Event struct {
	Type    string `json:"type"`
	Payload string `json:"payload"`
}

func main() {
	stream := strings.NewReader(`{"type":"click","payload":"btn-1"}
{"type":"scroll","payload":"page-2"}`)

	dec := json.NewDecoder(stream)
	for dec.More() {
		var ev Event
		if err := dec.Decode(&ev); err != nil {
			break
		}
		fmt.Printf("%s: %s\n", ev.Type, ev.Payload)
	}
	// → click: btn-1
	// → scroll: page-2
}

常见问题

json.Unmarshal和json.Decode有什么区别?
json.Unmarshal接受包含完整JSON文档的[]byte并填充结构体。json.NewDecoder包装io.Reader并增量解码JSON。当内存中已有完整JSON时(例如io.ReadAll之后),使用Unmarshal。当直接从HTTP响应体、文件或任何流式来源读取,且不希望缓冲整个载荷时,使用NewDecoder。
Go如何处理载荷中缺失的JSON字段?
缺失的JSON字段会将对应的Go结构体字段保留为零值:字符串为"",数字为0,布尔值为false,指针和切片为nil。若需要区分「字段缺失」和「字段存在但为零值」,使用*int或*string等指针类型。nil指针表示字段不存在;值为零的非nil指针表示字段被显式设置为0或""。
Go结构体字段为什么需要导出(首字母大写)才能用于JSON?
encoding/json包使用反射访问结构体字段,而Go的反射规则只允许访问导出(大写)字段。若字段以小写字母开头,encoding/json无法识别它,在序列化和反序列化时都会静默跳过。使用json结构体标签将导出的PascalCase字段映射到小写JSON键。
如何在Go中处理snake_case的JSON键?
添加包含确切JSON键名的json结构体标签。例如,JSON字段"user_name"映射到带有标签`json:"user_name"`的Go字段UserName。生成器会自动处理这一问题。encoding/json没有全局设置命名策略的选项,每个字段必须声明自己的标签。
能否将包含null值的JSON转换为Go?
可以。JSON null值映射为Go中的指针类型。像"age": null这样的字段会变为Age *int `json:"age"`。当JSON值为null时,Go指针为nil。当有具体值时,Go分配一个int并由指针引用。对于始终可为null的字段,使用指针是Go中的惯用做法。
如果JSON中包含超出Go int范围的数字会怎样?
Go的int是平台相关的(32位系统为32位,64位系统为64位)。对于JavaScript时间戳或数据库ID等大数字,请显式使用int64。如果JSON数字有小数部分,使用float64。对于超出float64精度的数字(例如大型金融值),使用json.Number,它保留原始字符串表示并允许自行解析。
此工具与JSON-to-Go-Struct有什么区别?
此工具生成注重encoding/json使用模式的Go类型定义:正确的结构体标签、适当的类型推断,以及对嵌套结构和数组的处理。本站的JSON转Go结构体工具专注于结构体脚手架。两者都能生成有效的Go代码,选择适合您工作流程的即可。无论选择哪个生成器,本页的结构体标签参考和类型映射表都很有参考价值。