Maison >développement back-end >Golang >Comment aplatir les structures JSON marshalées avec des membres anonymes dans Go ?

Comment aplatir les structures JSON marshalées avec des membres anonymes dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-29 07:35:31220parcourir

How to Flatten Marshaled JSON Structs with Anonymous Members in Go?

Aplatissement des structures JSON marshalées avec des membres anonymes dans Go

Lors du marshaling des données JSON dans Go, les membres anonymes peuvent introduire des complexités inattendues. Cet article explore une solution qui répond à ces défis.

Le problème

Considérez le code suivant :

<code class="go">type Hateoas struct {
    Anything
    Links map[string]string `json:"_links"`
}</code>

Lorsque Hateoas contient des membres anonymes, le marshaler JSON les traite sous forme de champs nommés réguliers, ce qui entraîne une imbrication indésirable :

<code class="json">{
    "Anything": {
        "id": 123,
        "name": "James Dean"
    },
    "_links": {
        "self": "http://user/123"
    }
}</code>

Solution : aplatissement basé sur la réflexion

Pour aplatir la structure JSON et éliminer l'imbrication supplémentaire, nous pouvons utiliser la réflexion :

<code class="go">subjectValue := reflect.Indirect(reflect.ValueOf(subject))
subjectType := subjectValue.Type()
for i := 0; i < subjectType.NumField(); i++ {
    field := subjectType.Field(i)
    name := subjectType.Field(i).Name
    out[field.Tag.Get("json")] = subjectValue.FieldByName(name).Interface()
}</code>

Cette boucle parcourt les champs de la structure, extrait leurs noms de balises JSON et les mappe à une map[string]interface{} aplatie. En utilisant la réflexion, nous évitons d'ajouter de nouveaux champs nommés et conservons la structure plate d'origine.

Exemple

Voici un exemple d'utilisation de cette solution :

<code class="go">import "reflect"

func MarshalHateoas(subject interface{}) ([]byte, error) {
    links := make(map[string]string)
    out := make(map[string]interface{})
    subjectValue := reflect.Indirect(reflect.ValueOf(subject))
    subjectType := subjectValue.Type()
    for i := 0; i < subjectType.NumField(); i++ {
        field := subjectType.Field(i)
        name := subjectType.Field(i).Name
        out[field.Tag.Get("json")] = subjectValue.FieldByName(name).Interface()
    }
    switch s := subject.(type) {
    case *User:
        links["self"] = fmt.Sprintf("http://user/%d", s.Id)
    case *Session:
        links["self"] = fmt.Sprintf("http://session/%d", s.Id)
    }
    out["_links"] = links
    return json.MarshalIndent(out, "", "    ")
}</code>

Avec Grâce à cette fonction MarshalHateoas améliorée, l'exemple de sortie JSON devient :

<code class="json">{
    "id": 123,
    "name": "James Dean",
    "_links": {
        "self": "http://user/123"
    }
}</code>

Conclusion

En tirant parti de la réflexion, nous pouvons aplatir efficacement les structures JSON avec des membres anonymes et obtenir la structure JSON souhaitée sans compromettre l'intégrité des données. . Cette solution fournit un moyen robuste de gérer des scénarios de sérialisation JSON complexes dans Go.

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