Maison >développement back-end >Golang >Comment désorganiser les champs JSON dynamiques dans Go en fonction d'une clé de type ?

Comment désorganiser les champs JSON dynamiques dans Go en fonction d'une clé de type ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-05 20:17:10490parcourir

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

Unmarshal Dynamic JSON basé sur une clé de type

Unmarshaling des données JSON complexes dans une structure Go peut être difficile lorsque la structure JSON contient des champs dynamiques de types variés. Cet article aborde un scénario spécifique dans lequel les champs JSON contiennent principalement des valeurs simples, mais parfois un champ dynamique avec une clé de type spécifique détermine le type de valeur du champ.

L'objectif est de créer une structure Go avec la même structure comme le JSON fourni, où le champ dynamique est représenté comme un type d'interface, permettant une gestion flexible en fonction de son type.

Une solution possible utilise la personnalisation suivante types :

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

type Something interface {
    GetType() string
}

Ensuite, créez des structures individuelles pour chaque type de champ dynamique :

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
}

Pour désorganiser le JSON dans cette structure, le BigStruct peut implémenter une méthode UnmarshalJSON personnalisée :

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
}

La méthode Unmarshal peut être appelée depuis UnmarshalJSON pour analyser la dynamique 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
}

Avec cette approche, vous pouvez regrouper les champs JSON dynamiques dans la structure Go sans introduire de champ d'espace réservé supplémentaire.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn