golang多JSON文档智能转换为Go结构体插件库json2go的使用
Golang多JSON文档智能转换为Go结构体插件库json2go的使用
json2go是一个用于从JSON输入创建Go类型表示的实用工具库。它可以智能地将多个JSON文档转换为适合所有输入的Go结构体。
为什么选择json2go?
现有的JSON转Go类型工具大多只能处理基本文档。json2go的目标是创建能够正确反序列化输入数据的类型,它通过双向的编组/解组测试用例来确保生成的类型是准确的。
安装CLI工具
go get github.com/m-zajac/json2go/...
使用方式
json2go可以作为CLI工具或Go包使用。
CLI使用示例
- 基本使用:
echo '{"x":1,"y":2}' | json2go
- 从API获取数据并转换:
curl -s https://api.punkapi.com/v2/beers?page=1&per_page=5 | json2go
- 从文件读取并转换:
cat data.json | json2go
包使用示例
inputs := []string{
`{"x": 123, "y": "test", "z": false}`,
`{"a": 123, "x": 12.3, "y": true}`,
}
parser := json2go.NewJSONParser("Document")
for _, in := range inputs {
parser.FeedBytes([]byte(in))
}
res := parser.String()
fmt.Println(res)
示例输出
示例1
输入JSON:
{
"line": {
"point1": {
"x": 12.1,
"y": 2
},
"point2": {
"x": 12.1,
"y": 2
}
}
}
输出Go结构体:
type Document struct {
Line struct {
Point1 Point `json:"point1"`
Point2 Point `json:"point2"`
} `json:"line"`
}
type Point struct {
X float64 `json:"x"`
Y int `json:"y"`
}
示例2
输入JSON:
[
{
"name": "water",
"type": "liquid",
"boiling_point": {
"units": "C",
"value": 100
}
},
{
"name": "oxygen",
"type": "gas",
"density": {
"units": "g/L",
"value": 1.429
}
},
{
"name": "carbon monoxide",
"type": "gas",
"dangerous": true,
"boiling_point": {
"units": "C",
"value": -191.5
},
"density": {
"units": "kg/m3",
"value": 789
}
}
]
输出Go结构体:
type Document []struct {
BoilingPoint *UnitsValue `json:"boiling_point,omitempty"`
Dangerous *bool `json:"dangerous,omitempty"`
Density *UnitsValue `json:"density,omitempty"`
Name string `json:"name"`
Type string `json:"type"`
}
type UnitsValue struct {
Units string `json:"units"`
Value float64 `json:"value"`
}
高级测试用例
这是一个测试json2go能力的复杂示例:
输入JSON:
[{"date":"2020-10-03T15:04:05Z","text":"txt1","doc":{"x":"x"}},{"date":"2020-10-03T15:05:02Z","_doc":false,"arr":[[1,null,1.23]]},{"bool":true,"doc":{"y":123}}]
正确的输出:
type Document []struct {
Arr [][]*float64 `json:"arr,omitempty"` // 应该是双重嵌套数组;应该是指针类型因为值中有null
Bool *bool `json:"bool,omitempty"` // 不应该是bool类型,因为当键缺失时会得到错误信息
Date *time.Time `json:"date,omitempty"` // 也可以是string或*string
Doc *struct {
X *string `json:"x,omitempty"` // 应该是指针,因为键不是在所有文档中都存在
Y *int `json:"y,omitempty"` // 应该是指针,因为键不是在所有文档中都存在
} `json:"doc,omitempty"` // 应该是指针,因为键不是数组中的所有文档中都存在
Doc2 *bool `json:"_doc,omitempty"` // "_doc"键的属性(与"doc"不同!)。类型与Bool属性相同
Text *string `json:"text,omitempty"` // 也可以是string
}
json2go能够处理复杂的JSON结构,并生成准确的Go类型定义,确保类型安全性和数据的正确反序列化。
更多关于golang多JSON文档智能转换为Go结构体插件库json2go的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang多JSON文档智能转换为Go结构体插件库json2go的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
json2go:智能JSON转Go结构体的强大工具
json2go是一个非常有用的工具,它能够自动将JSON文档转换为对应的Go结构体定义,极大提高了开发效率。下面我将详细介绍如何使用这个工具。
json2go简介
json2go是一个能够将JSON样本数据自动转换为Go结构体定义的库/工具。它特别适合以下场景:
- 处理API响应数据
- 解析配置文件
- 处理动态JSON数据
- 快速原型开发
安装方法
go get -u github.com/mholt/json-to-go
或者使用在线版本:https://mholt.github.io/json-to-go/
基本使用示例
1. 简单JSON转换
假设有以下JSON:
{
"name": "John Doe",
"age": 30,
"isActive": true,
"address": {
"street": "123 Main St",
"city": "Anytown"
}
}
使用json2go转换后会生成:
type AutoGenerated struct {
Name string `json:"name"`
Age int `json:"age"`
IsActive bool `json:"isActive"`
Address Address `json:"address"`
}
type Address struct {
Street string `json:"street"`
City string `json:"city"`
}
2. 处理数组
{
"users": [
{
"id": 1,
"name": "Alice"
},
{
"id": 2,
"name": "Bob"
}
]
}
转换结果:
type AutoGenerated struct {
Users []User `json:"users"`
}
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
高级功能
1. 自定义结构体名称
// 在转换时可以指定根结构体名称
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
2. 处理空值和可选字段
{
"name": "John",
"age": null
}
转换结果(使用指针表示可选字段):
type AutoGenerated struct {
Name string `json:"name"`
Age *int `json:"age"`
}
3. 处理时间格式
{
"createdAt": "2023-01-01T12:00:00Z"
}
转换结果:
type AutoGenerated struct {
CreatedAt time.Time `json:"createdAt"`
}
实际应用示例
下面是一个完整的示例,展示如何使用生成的代码解析JSON:
package main
import (
"encoding/json"
"fmt"
"time"
)
// 使用json2go生成的代码
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
CreatedAt time.Time `json:"createdAt"`
IsActive bool `json:"isActive"`
Roles []string `json:"roles"`
}
func main() {
jsonData := `{
"id": 123,
"name": "Alice",
"email": "alice@example.com",
"createdAt": "2023-01-01T12:00:00Z",
"isActive": true,
"roles": ["admin", "user"]
}`
var user User
err := json.Unmarshal([]byte(jsonData), &user)
if err != nil {
panic(err)
}
fmt.Printf("User: %+v\n", user)
fmt.Printf("Roles: %v\n", user.Roles)
}
其他替代工具
除了json2go,还有其他类似工具:
- quicktype - 支持多种语言转换
- json-to-go - 在线转换工具
- gojson - 命令行工具
最佳实践
- 验证生成的结构体:自动生成的结构体可能需要手动调整
- 处理嵌套结构:对于复杂JSON,可能需要调整嵌套层次
- 添加文档注释:为生成的结构体添加有意义注释
- 考虑使用指针:对于可选字段,使用指针可以更好处理null值
json2go极大简化了Go开发中处理JSON数据的工作,特别是在处理复杂API响应时。通过自动生成结构体定义,开发者可以专注于业务逻辑而非数据结构的定义。