首页 >后端开发 >Golang >如何根据类型键解组 Go 中的动态 JSON 字段?

如何根据类型键解组 Go 中的动态 JSON 字段?

Susan Sarandon
Susan Sarandon原创
2024-12-05 20:17:10496浏览

How to Unmarshal Dynamic JSON Fields in Go Based on a Type Key?

基于类型键解组动态 JSON

当 JSON 结构包含动态字段时,将复杂的 JSON 数据解组到 Go 结构中可能具有挑战性不同类型的。本文讨论了一个特定场景,其中 JSON 字段主要包含简单值,但有时具有特定类型键的动态字段决定字段值的类型。

目标是创建一个具有相同结构的 Go 结构体结构作为提供的 JSON,其中动态字段表示为接口类型,允许根据其类型进行灵活处理。

一种可能的解决方案利用以下自定义类型:

type BigStruct struct {
    SomeData     string    `json:"some_data"`
    DynamicField Something `json:"dynamic_field"`
    OtherData    string    `json:"other_data"`
}

type Something interface {
    GetType() string
}

然后,为每个动态字段类型创建单独的结构:

type BaseDynamicType struct {
    Type string `json:"type"`
}

type DynamicTypeA struct {
    BaseDynamicType
    Name string `json:"name"`
}

type DynamicTypeB struct {
    BaseDynamicType
    Address string `json:"address"`
}

func (d *BaseDynamicType) GetType() string {
    return d.Type
}

要将 JSON 解组到此结构中,BigStruct 可以实现自定义 UnmarshalJSON 方法:

func (b *BigStruct) UnmarshalJSON(data []byte) error {
    var tmp struct {
        SomeData     string          `json:"some_data"`
        DynamicField json.RawMessage `json:"dynamic_field"`
        OtherData    string          `json:"other_data"`
    }

    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }
    b.Unmarshal(tmp.DynamicField)

    return nil
}

可以从 UnmarshalJSON 中调用 Unmarshal 方法来解析动态field:

func (b *BigStruct) Unmarshal(data json.RawMessage) error {
    switch UnmarshalledType(data) {
    case "A":
        var a DynamicTypeA
        if err := json.Unmarshal(data, &a); err != nil {
            return err
        }

        b.DynamicField = &a
    case "B":
        var b DynamicTypeB
        if err := json.Unmarshal(data, &b); err != nil {
            return err
        }

        b.DynamicField = &b
    }

    return nil
}

func UnmarshalledType(b json.RawMessage) string {
    var typ struct {
        Type string `json:"type"`
    }

    if err := json.Unmarshal(b, &typ); err != nil {
        log.Fatalf("Error extracting type from RawMessage: %v", err)
    }

    return typ.Type
}

通过这种方法,您可以将动态 JSON 字段解组到 Go 结构中,而无需引入额外的占位符字段。

以上是如何根据类型键解组 Go 中的动态 JSON 字段?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn