使用包装器(结构或映射)
您可以使用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 上的所有示例。
使用自定义编组
如果您不想使用包装器结构或映射,则需要使用自定义编组,但这很简单:
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 的封送值不必这样做。
测试它:
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 上试试这个。