为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
一只萌萌小番薯 2023-04-04 14:21:16
我们需要为嵌套在不需要自定义解组器的多个其他结构中的结构使用自定义解组器。我们有很多结构类似于B下面定义的结构(类似于嵌套A)。代码的输出是true false 0(预期的true false 2)。有任何想法吗?在此处转到 Playground 示例。package mainimport (    "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)}编辑:问题在此处被标记为重复,但A显式填写字段会使我们的 API 混乱。同样在创建A一个显式字段之后,结果是false false 2这样它根本没有帮助。
查看完整描述

1 回答

?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

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

这是我能想到的最简单的方法,可以根据您不更改数据类型的约束使其工作A

  1. 让 B 嵌入另一个包含 A 中不包含的字段的结构 C。

  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

}


查看完整回答
反对 回复 2023-04-04
  • 1 回答
  • 0 关注
  • 82 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信