Aufruf von json.Unmarshal innerhalb der UnmarshalJSON-Funktion ohne Stapelüberlauf
In benutzerdefinierten UnmarshalJSON-Implementierungen kann der Aufruf von json.Unmarshal(b, type) dazu führen Überläufe stapeln. Dies liegt daran, dass der JSON-Decoder wiederholt nach benutzerdefinierten UnmarshalJSON-Implementierungen sucht, was zu einer endlosen Rekursion führt.
Um dieses Problem zu vermeiden, erstellen Sie einen neuen Typ mit dem Schlüsselwort „type“ und weisen Sie ihm mithilfe einer Typkonvertierung Ihren ursprünglichen Wert zu. Dies ist möglich, weil dem neuen Typ der ursprüngliche Typ als zugrunde liegender Typ zugrunde liegt.
Beispiel:
Angenommen, wir haben einen Personentyp mit einem Altersfeld. Um sicherzustellen, dass das Alter nicht negativ sein kann, können wir UnmarshalJSON wie folgt implementieren:
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 }
Bei diesem Ansatz erstellt Typ person2 einen neuen Typ ohne Methoden und verhindert so eine Rekursion. Beim Unmarshaling der Daten werden sie dem Typ „Person2“ und dann dem ursprünglichen Typ „Person“ zugewiesen, was eine Nachbearbeitung ermöglicht.
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) }
Ausgabe:
<nil> &{Bob 10} <nil> &{Bob 0}
Dies zeigt, wie UnmarshalJSON angepasst werden kann, ohne einen Stapel zu verursachen Überläufe.
Das obige ist der detaillierte Inhalt vonWie vermeide ich einen Stapelüberlauf, wenn ich json.Unmarshal in UnmarshalJSON verwende?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!