对嵌套结构使用自定义解组时,GoLang 结构无法正确解组

Ale*_*giu 4 json struct nested go unmarshalling

我们需要对嵌套在多个其他结构中的结构使用自定义解组器,而这些结构不需要自定义解组器。我们有很多与B下面定义的结构类似的结构(类似于嵌套A)。代码的输出是true false 0(预期的true false 2)。有任何想法吗?


Go Playground 示例在这里

package main

import (
    "fmt"
    "encoding/json"
)

type A struct {
    X bool `json:"x"`
    Y bool `json:"y"`
}

type B struct {
    A
    Z int `json:"z"`
}

func (a *A) UnmarshalJSON(bytes []byte) error {
    var aa struct {
        X string `json:"x"`
        Y string `json:"y"`
    }
    json.Unmarshal(bytes, &aa)

    a.X = aa.X == "123"
    a.Y = aa.Y == "abc"
    return nil
}

const myJSON = `{"x": "123", "y": "fff", "z": 2}`

func main() {
    var b B
    json.Unmarshal([]byte(myJSON), &b)
    fmt.Print(b.X," ",b.Y," ",b.Z)
}
Run Code Online (Sandbox Code Playgroud)

编辑:问题在这里被标记为重复,但创建A显式字段将使我们的 API 混乱。此外,在创建A显式字段之后,结果是false false 2根本没有帮助。

svs*_*vsd 5

由于B嵌入AA.UnmarshalJSON()因此暴露为B.UnmarshalJSON()。因此,B实现json.Unmarshaler并因此json.Unmarshal()调用B.UnmarshalJSON()仅解组A的字段。B.Z这就是未从 JSON 中设置的原因。

这是我能想到的最简单的方法,让它根据不更改数据类型的约束工作A

  1. 让 B 嵌入另一个结构体 C,其中包含 A 中未包含的字段。
  2. 为 B 编写一个 UnmarshalJSON() 方法,将相同的 JSON 解组到 BA 和 BC 中。使用 A 中没有的字段定义另一个类型 C 的优点是,您可以将其解组委托给 json 包。

使用新B.UnmarshalJSON()方法,您现在可以完全控制外部字段的编组A

type A struct {
    X bool `json:"x"`
    Y bool `json:"y"`
}

func (a *A) UnmarshalJSON(bytes []byte) error {
    // the special unmarshalling logic here
}

type C struct {
    Z int `json:"z"`
}

type B struct {
    A
    C
}

func (b *B) UnmarshalJSON(bytes []byte) error {
    if err := json.Unmarshal(bytes, &b.A); err != nil {
        return err
    }
    if err := json.Unmarshal(bytes, &b.C); err != nil {
        return err
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)