Maison >développement back-end >Golang >Comment éviter le débordement de pile lors de l'utilisation de json.Unmarshal dans UnmarshalJSON ?

Comment éviter le débordement de pile lors de l'utilisation de json.Unmarshal dans UnmarshalJSON ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-19 22:50:15124parcourir

How to Avoid Stack Overflow When Using json.Unmarshal Inside UnmarshalJSON?

Appel de json.Unmarshal dans la fonction UnmarshalJSON sans débordement de pile

Dans les implémentations personnalisées d'UnmarshalJSON, l'appel de json.Unmarshal(b, type) peut entraîner pour empiler les débordements. Cela se produit parce que le décodeur JSON vérifie à plusieurs reprises les implémentations personnalisées d'UnmarshalJSON, ce qui entraîne une récursion sans fin.

Pour éviter ce problème, créez un nouveau type à l'aide du mot-clé type et attribuez-lui votre valeur d'origine à l'aide d'une conversion de type. Ceci est possible car le nouveau type a le type d'origine comme type sous-jacent.

Exemple :

Supposons que nous ayons un type Personne avec un champ Âge. Pour garantir que l'âge ne peut pas être négatif, nous pouvons implémenter UnmarshalJSON comme suit :

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

func (p *Person) UnmarshalJSON(data []byte) error {
    type person2 Person
    if err := json.Unmarshal(data, (*person2)(p)); err != nil {
        return err
    }

    // Post-processing after unmarshaling:
    if p.Age < 0 {
        p.Age = 0
    }
    return nil
}

Dans cette approche, le type person2 crée un nouveau type sans méthode, empêchant ainsi la récursion. Lorsque les données ne sont pas marshalées, elles sont affectées au type personne2 puis au type Personne d'origine, permettant le post-traitement.

Test :

import (
    "encoding/json"
    "fmt"
)

func main() {
    var p *Person
    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":10}`), &p))
    fmt.Println(p)

    fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":-1}`), &p))
    fmt.Println(p)
}

Sortie :

<nil>
&{Bob 10}
<nil>
&{Bob 0}

Cela montre comment personnaliser UnmarshalJSON sans provoquer de pile déborde.

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