gpt4 book ai didi

json - 递归数据模型的golang json序列化/反序列化

转载 作者:IT王子 更新时间:2023-10-29 01:42:06 44 4
gpt4 key购买 nike

假设我有:

type IObject interface {
}

type Item struct {
Description string
Data []byte
}

type FunctionX1 struct {
Object IInclusionObject
}

type FunctionX2 struct {
Object1 IInclusionObject
Object2 IInclusionObject
}

我希望能够序列化/反序列化一个模型,其中 Item, FunctionX1 FunctionX2 它们都实现了 IObject 并且它们可以任意深度地指向彼此。

请注意,我不希望:FunctionX1{Item{"foo", []byte("bar")}} 被序列化为:

"object": {
"Description": "foo"
"Data": ...
}

而是:

"FunctionX1": {
"item": {
"Description": "foo"
"Data": ...
}
}

我需要做我自己的 JSON 编码器吗?我似乎无法使用现有的编码器。

相关问题以备我需要时使用。是否有 JSON 美化器,我可以在其中流式传输有效但随机格式化的 JSON 并输出漂亮的版本(注意 JSON 可能非常大 - 我不想生成,解析生成格式化)。

最佳答案

使用包装器(结构或映射)

您可以使用 struct tags将结构的字段映射到 JSON 中/来自 JSON 的不同名称。因此,您可以将 "Object" 更改为 "item":

type FunctionX1 struct {
Object IInclusionObject `json:"item"`
}

但如果您希望 "FunctionX1" 出现在 JSON 文本中,您仍然需要一个包装器结构或映射。例如:

f := FunctionX1{Item{"foo", []byte("bar")}}

if data, err := json.Marshal(map[string]interface{}{"FunctionX1": f}); err != nil {
panic(err)
} else {
fmt.Println(string(data))
}

输出:

{"FunctionX1":{"item":{"Description":"foo","Data":"YmFy"}}}

或者使用包装器结构:

type Wrapper struct {
FunctionX1 FunctionX1
}

f := FunctionX1{Item{"foo", []byte("bar")}}

if data, err := json.Marshal(Wrapper{f}); err != nil {
panic(err)
} else {
fmt.Println(string(data))
}

输出是一样的:

{"FunctionX1":{"item":{"Description":"foo","Data":"YmFy"}}}

如果你想要格式化的 JSON,你可以使用 json.MarshalIndent()进行编码:

if data, err := json.MarshalIndent(Wrapper{f}, "", "  "); err != nil {
panic(err)
} else {
fmt.Println(string(data))
}

输出:

{
"FunctionX1": {
"item": {
"Description": "foo",
"Data": "YmFy"
}
}
}

尝试 Go Playground 上的所有示例.

使用自定义编码(marshal)处理

如果您不想使用包装器结构或映射,则需要使用自定义编码,但这非常简单:

type FunctionX1 struct {
Object IInclusionObject `json:"item"`
}

func (f FunctionX1) MarshalJSON() ([]byte, error) {
type FunctionX1_ FunctionX1
return json.Marshal(map[string]interface{}{"FunctionX1": FunctionX1_(f)})
}

实际上,我们将包装移动到 MarshalJSON() 方法中,因此其他人不必对 FunctionX1 的值进行编码(marshal)处理。

测试它:

f := FunctionX1{Item{"foo", []byte("bar")}}

if data, err := json.Marshal(f); err != nil {
panic(err)
} else {
fmt.Println(string(data))
}

if data, err := json.MarshalIndent(f, "", " "); err != nil {
panic(err)
} else {
fmt.Println(string(data))
}

请注意,MarshalJSON() 中的新 FunctionX1_ 类型是为了避免无限“递归”。

输出:

{"FunctionX1":{"item":{"Description":"foo","Data":"YmFy"}}}
{
"FunctionX1": {
"item": {
"Description": "foo",
"Data": "YmFy"
}
}
}

Go Playground 上试试这个.

关于json - 递归数据模型的golang json序列化/反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38017212/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com