Maison >développement back-end >Golang >Comment marshaler correctement JSON() pour les structures intégrées avec un marshaling personnalisé ?

Comment marshaler correctement JSON() pour les structures intégrées avec un marshaling personnalisé ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-07 10:40:16834parcourir

How to Correctly MarshalJSON() for Embedded Structs with Custom Marshaling?

Manière idiomatique d'intégrer une structure avec la méthode MarshalJSON() personnalisée

Problème :

Comment pouvons-nous encoder une structure avec une structure intégrée qui a une méthode MarshalJSON() personnalisée ? Le résultat attendu est de préserver le marshaling personnalisé de la structure intégrée tout en codant également les champs de la structure externe.

Exemple :

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

Lorsque la personne intégrée struct a une méthode MarshalJSON() personnalisée :

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}

Le marshalage d'une instance d'employé s'interrompt, ce qui entraîne dans :

{"name": "BOB"}

Solution :

Au lieu d'implémenter MarshalJSON() sur Person, créez un nouveau type Name qui implémente MarshalJSON(). Ensuite, modifiez Person pour utiliser ce type de nom :

type Name string

func (n Name) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(string(n)),
    })
}

type Person struct {
    Name Name `json:"name"`
}

Cela permet d'appliquer la logique de marshaling personnalisée au champ Nom tout en continuant à encoder les champs Employé comme prévu.

Solution générique :

Pour une solution plus générique, implémentez MarshalJSON() sur la structure externe. Alors que les méthodes du type interne sont promues au type externe, le type externe peut ensuite regrouper le résultat dans une structure générique telle que map[string]interface{} et ajouter ses propres champs.

Exemple :

type Person struct {
    Name string `json:"name"`
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

func (e *Employee) MarshalJSON() ([]byte, error) {
    b, err := e.Person.MarshalJSON()
    if err != nil {
        return nil, err
    }

    var m map[string]interface{}
    if err := json.Unmarshal(b, &m); err != nil {
        return nil, err
    }

    m["jobRole"] = e.JobRole
    return json.Marshal(m)
}

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