对于嵌套在多个不需要自定义拆组器的其他结构中的结构,我们需要使用自定义拆组器。我们有很多类似于下面定义的B
结构的结构(类似于嵌套A
中的结构)。代码的输出为true false 0
(预期为true false 2
)。有什么想法吗?
转到Playground示例here。
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)
}
编辑:问题被标记为重复的here,但是将A
设为显式字段将使我们的API混乱。同样,在将A
设为显式字段后,结果为false false 2
,因此完全没有帮助。
答案 0 :(得分:0)
由于B
嵌入A
,因此A.UnmarshalJSON()
被公开为B.UnmarshalJSON()
。因此,B
实现了json.Unmarshaler
,结果json.Unmarshal()
调用了B.UnmarshalJSON()
,这仅解组了A
的字段。这就是未从JSON设置B.Z
的原因。
这是我想出的最简单的方法,可以根据您的约束而不更改A
中的数据类型:
使用新的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
}