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使用示例

  1. 基本使用:
echo '{"x":1,"y":2}' | json2go
  1. 从API获取数据并转换:
curl -s https://api.punkapi.com/v2/beers?page=1&per_page=5 | json2go
  1. 从文件读取并转换:
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

1 回复

更多关于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,还有其他类似工具:

  1. quicktype - 支持多种语言转换
  2. json-to-go - 在线转换工具
  3. gojson - 命令行工具

最佳实践

  1. 验证生成的结构体:自动生成的结构体可能需要手动调整
  2. 处理嵌套结构:对于复杂JSON,可能需要调整嵌套层次
  3. 添加文档注释:为生成的结构体添加有意义注释
  4. 考虑使用指针:对于可选字段,使用指针可以更好处理null值

json2go极大简化了Go开发中处理JSON数据的工作,特别是在处理复杂API响应时。通过自动生成结构体定义,开发者可以专注于业务逻辑而非数据结构的定义。

回到顶部