Golang递归将JSON转换为结构体?

huangapple go评论91阅读模式
英文:

golang recursive json to struct?

问题

你好!对于你的问题,你可以尝试使用递归函数来处理未知数量的子元素。这样可以避免在结构体中嵌套多个相同的结构体。以下是一个示例代码:

type Node struct {
	ID       int         `json:"id"`
	Name     string      `json:"name"`
	Children []Node      `json:"children"`
}

func main() {
	data := []byte(`[{
		"id": 1,
		"name": "aaa",
		"children": [{
			"id": 2,
			"name": "bbb",
			"children": [{
				"id": 3,
				"name": "ccc",
				"children": [{
					"id": 4,
					"name": "ddd",
					"children": []
				}]
			}]
		}]
	}]`)

	var nodes []Node
	err := json.Unmarshal(data, &nodes)
	if err != nil {
		fmt.Println("JSON 解析错误:", err)
		return
	}

	// 打印节点信息
	printNodes(nodes, 0)
}

func printNodes(nodes []Node, level int) {
	prefix := strings.Repeat("\t", level)
	for _, node := range nodes {
		fmt.Printf("%sID: %d, Name: %s\n", prefix, node.ID, node.Name)
		printNodes(node.Children, level+1)
	}
}

这样,你可以通过递归函数 printNodes 来遍历并打印所有节点的信息。这种方式更加灵活和优雅,可以处理任意数量的子元素。

希望这可以帮助到你!如果你有任何其他问题,请随时问我。

英文:

I used to write python, just started to contact golang

my json for example,children unknow numbers,may be three ,may be ten。

[{
	"id": 1,
	"name": "aaa",
	"children": [{
		"id": 2,
		"name": "bbb",
		"children": [{
			"id": 3,
			"name": "ccc",
			"children": [{
				"id": 4,
				"name": "ddd",
				"children": []
			}]
		}]
	}]
}]

i write struct

	
type AutoGenerated []struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	Children []struct {
		ID       int    `json:"id"`
		Name     string `json:"name"`
		Children []struct {
			ID       int    `json:"id"`
			Name     string `json:"name"`
			Children []struct {
				ID       int           `json:"id"`
				Name     string        `json:"name"`
				Children []interface{} `json:"children"`
			} `json:"children"`
		} `json:"children"`
	} `json:"children"`
}

but i think this too stupid。
how to optimize?

答案1

得分: 3

您可以在其定义中重用AutoGenerated类型:

type AutoGenerated []struct {
    ID       int           `json:"id"`
    Name     string        `json:"name"`
    Children AutoGenerated `json:"children"`
}

进行测试:

var o AutoGenerated

if err := json.Unmarshal([]byte(src), &o); err != nil {
    panic(err)
}

fmt.Println(o)

(src是您的JSON输入字符串。)

输出结果(在Go Playground上尝试):

[{1 aaa [{2 bbb [{3 ccc [{4 ddd []}]}]}]}]

如果AutoGenerated本身不是一个切片,那么它更容易理解和使用:

type AutoGenerated struct {
    ID       int             `json:"id"`
    Name     string          `json:"name"`
    Children []AutoGenerated `json:"children"`
}

然后使用它/测试它:

var o []AutoGenerated

if err := json.Unmarshal([]byte(src), &o); err != nil {
    panic(err)
}

fmt.Println(o)

输出结果相同。在Go Playground上尝试这个示例。

英文:

You can reuse the AutoGenerated type in its definition:

type AutoGenerated []struct {
	ID       int           `json:"id"`
	Name     string        `json:"name"`
	Children AutoGenerated `json:"children"`
}

Testing it:

var o AutoGenerated

if err := json.Unmarshal([]byte(src), &o); err != nil {
	panic(err)
}

fmt.Println(o)

<sup>(src is your JSON input string.)</sup>

Output (try it on the Go Playground):

[{1 aaa [{2 bbb [{3 ccc [{4 ddd []}]}]}]}]

Also it's easier to understand and work with if AutoGenerated itself is not a slice:

type AutoGenerated struct {
	ID       int             `json:&quot;id&quot;`
	Name     string          `json:&quot;name&quot;`
	Children []AutoGenerated `json:&quot;children&quot;`
}

Then using it / testing it:

var o []AutoGenerated

if err := json.Unmarshal([]byte(src), &amp;o); err != nil {
	panic(err)
}

fmt.Println(o)

Outputs the same. Try this one on the Go Playground.

huangapple
  • 本文由 发表于 2023年1月14日 21:52:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75118431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定