复合结构的 JSON 封送处理,它们都实现了 MarshalJSON()



我最近遇到了以下问题,但没有找到任何解决方案。我在 Go 中有两种结构类型,我们称它们为父级和子级。 子级有一个匿名字段,类型为 *Parent。但是,Parent 有一个名为"ID"的字段,它具有第三个结构的类型,我们将该类型称为"IDType"(在我的实际问题中,这是一种方言/sql。空英特64(。IDType 有一个 int 字段和一个布尔字段。

问题如下:父级和子级都实现了 MarshalJSON((,因为对于父级,我只希望 JSON 中的 int 字段和子级相同。但是,似乎两个 MarshalJSON 都推断出只有父级的值被编码在最终的 JSON 中。

也许一个最小的例子更容易理解:

package main
import (
"encoding/json"
"fmt"
"os"
)
type IDType struct {
Value int
Valid bool
}
type Parent struct {
ID         IDType `json:"id"`
SomeString string `json:"some_string"`
}
type Child struct {
*Parent
Status int `json:"status"`
}
func (parent *Parent) MarshalJSON() ([]byte, error) {
type Alias Parent
fmt.Println("Parent")
return json.Marshal(struct {
*Alias
ID int `json:"id"`
}{
Alias: (*Alias)(parent),
ID:    parent.ID.Value,
})
}
func (child *Child) MarshalJSON() ([]byte, error) {
type Alias Child
fmt.Println("Child")
return json.Marshal(struct {
*Alias
Status int `json:"status"`
}{
Alias:  (*Alias)(child),
Status: child.Status,
})
}
func main() {
ID := IDType{Value: 1, Valid: true}
parent := Parent{ID: ID, SomeString: "Hello"}
child := Child{Parent: &Parent{ID: ID, SomeString: "Hello"}, Status: 1}
json.NewEncoder(os.Stdout).Encode(&parent)
json.NewEncoder(os.Stdout).Encode(&child)
}

输出为:

Parent
{"some_string":"Hello","id":1}
Child
Parent
{"some_string":"Hello","id":1}

我期待这样的东西:

Parent
{"some_string":"Hello","id":1}
Child
Parent
{"some_string":"Hello","id":1, "status": 1}

由于自定义 ID 封送处理,您似乎只定义了自定义封送处理逻辑。仅为未嵌入的IDType类型定义自定义封送处理,因此封送其他类型不会造成任何麻烦:

func (id *IDType) MarshalJSON() ([]byte, error) {
return json.Marshal(id.Value)
}

并且不需要其他自定义封送处理。这样,输出将是:

{"id":1,"some_string":"Hello"}
{"id":1,"some_string":"Hello","status":1}

在Go Playground上尝试一下。

您应该具有指向父级的命名指针或父级的嵌入值。

选项 1 将为您提供所需的 JSON。

type Child struct {
Parent
Status int `json:"status"`
}
>> {"some_string":"Hello","id":1, "status": 1}

选项 2 将父节点作为子节点。

type Child struct {
Parent *Parent
Status int `json:"status"`
}
>> {Parent: {"some_string":"Hello","id":1}, "status": 1}

另一个笨拙的选择是分别封送父子,然后通过剪切最后一个/第一个字符手动加入,与,连接并换入{}

最新更新