新手 golang 程序员在这里。我正在用 go 重写 java 应用程序。java 应用程序使用一个对象模型,该模型利用 Jackson 的多态类型功能来处理与 JSON 的编组/解组。假设我无法更改 JSON 对象的形状。
鉴于 go 提供的多态性是 interface{},因此就多态性而言,提出一个提供相同使用模式的“对象模型”一直是一个挑战。
我第一次尝试解决这个问题看起来像这样:
type Thing struct {
ID string `json:"id"`
Type string `json:"@type"`
}
type SpecificThing struct {
Thing
SpecificField string `json:"specificField"`
}
type AnotherSpecificThing struct {
Thing
AnotherSpecificField string `json:"anotherSpecificField"`
}
但这需要将具体的子类型实例传递给 unmarshal 方法。
我试图通过创建“Union Structs”作为编组和解组的工具来解决这个问题:
type Thing struct {
ID string `json:"id"`
Type string `json:"@type"`
Payload interface{} `json:"-"`
}
type SpecificThing struct {
SpecificField string `json:"specificField"`
}
type AnotherSpecificThing struct {
AnotherSpecificField string `json:"anotherSpecificField"`
}
type superThing struct {
ID string `json:"id"`
Type string `json:"@type"`
*SpecificThing
*AnotherSpecificThing
}
func (t *Thing) UnmarshalJSON(b []byte) error {
//error checking omitted for brevity
var st superThing
_ = json.Unmarshal(b, &st)
t.ID = st.ID
t.Type = st.Type
switch t.Type {
case "specificThing":
t.Payload = st.SpecificThing
case "anotherSpecificThing":
t.Payload = st.AnotherSpecificThing
}
return nil
}
func TestUnmarshal(t *testing.T) {
data := []byte(`
{
"id":"some id",
"@type":"specificThing",
"specificField": "some specific field value"
}
`)
var th Thing
_ = json.Unmarshal(data, &th)
}
就能够编组和解组这个动态 JSON 而言,这工作得很好。缺点是模型的使用者需要在有效负载上进行类型断言才能与子类型交互才能完成任何实际工作。理想情况下,是否有一种解决方案可以允许传递“事物”抽象级别,并且还可以在需要时与子类型进行交互?根据阅读,接口可以用于这种场景,但我正在努力了解该模型将如何利用它们。想法?
倚天杖
相关分类