Maison >développement back-end >Golang >Comment éviter le débordement de pile lors de l'utilisation de json.Unmarshal dans 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!