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
Libérer: 2024-12-19 22:50:15
original
203 Les gens l'ont consulté

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
}
Copier après la connexion

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)
}
Copier après la connexion

Sortie :

<nil>
&{Bob 10}
<nil>
&{Bob 0}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal