Heim > Backend-Entwicklung > Golang > Wie vermeide ich einen Stapelüberlauf, wenn ich json.Unmarshal in UnmarshalJSON verwende?

Wie vermeide ich einen Stapelüberlauf, wenn ich json.Unmarshal in UnmarshalJSON verwende?

Barbara Streisand
Freigeben: 2024-12-19 22:50:15
Original
115 Leute haben es durchsucht

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

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
}
Nach dem Login kopieren

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)
}
Nach dem Login kopieren

Ausgabe:

<nil>
&{Bob 10}
<nil>
&{Bob 0}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage