我们需要为嵌套在不需要自定义解码器的多个其他结构中的结构使用自定义解码器。我们有很多结构类似于下面定义的 B
结构(类似于嵌套 A
)。代码的输出是 true false 0
(预期的 true false 2
)。有什么想法吗?
Go 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
,因此它根本没有帮助。
最佳答案
由于 B
嵌入了 A
,A.UnmarshalJSON()
被公开为 B.UnmarshalJSON()
。因此,B
实现了 json.Unmarshaler
,因此 json.Unmarshal()
调用了 B.UnmarshalJSON()
只解码 A
的字段。这就是 B.Z
没有从 JSON 中设置的原因。
这是我能想到的最简单的方法,可以根据您不更改 A
中的数据类型的限制使其工作:
- 让 B 嵌入另一个包含 A 中不包含的字段的结构 C。
- 为 B 编写一个 UnmarshalJSON() 方法,该方法将相同的 JSON 解码为 B.A 和 B.C。使用不在 A 中的字段定义另一个类型 C 的优点是您可以将其解码委托(delegate)给 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
}
关于json - 对嵌套结构使用自定义解码时,GoLang 结构无法正确解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52294027/