Heim >Backend-Entwicklung >Golang >Wie kann ich eine Struktur mit einem benutzerdefinierten „MarshalJSON()' in Go idiomatisch einbetten?

Wie kann ich eine Struktur mit einem benutzerdefinierten „MarshalJSON()' in Go idiomatisch einbetten?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-06 13:18:11278Durchsuche

How to Idiomatically Embed a Struct with a Custom `MarshalJSON()` in Go?

Idiomatische Methode zum Einbetten einer Struktur mit einem benutzerdefinierten MarshalJSON()

Die Herausforderung entsteht, wenn eine eingebettete Struktur eine benutzerdefinierte MarshalJSON()-Methode definiert, was zu unerwartetem JSON-Serialisierungsverhalten führt beim Versuch, die enthaltende Struktur zu Marshallen.

Hintergrund

Berücksichtigen Sie Folgendes Folgende Strukturdefinitionen:

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

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

Das Marshallen der Employee-Struktur wie erwartet ist unkompliziert:

p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))

Ausgabe:

{"name":"Bob","jobRole":"Sales"}

Das Problem

Die Definition einer benutzerdefinierten MarshalJSON()-Methode für die eingebettete Struktur, wie unten gezeigt, stört jedoch die Absicht Serialisierung:

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}

Das Marshalling des Mitarbeiters erzeugt nun eine Ausgabe, bei der das Namensfeld in Großbuchstaben umgewandelt wird, aber das JobRole-Feld fehlt:

{"name":"BOB"}

Idiomatische Lösung

Zu pflegen Um das gewünschte Serialisierungsverhalten zu erreichen, vermeiden Sie die Definition einer MarshalJSON()-Methode für die eingebettete Struktur (Person). Erstellen Sie stattdessen einen separaten Typ, der die benutzerdefinierte Marshalling-Logik kapselt, und betten Sie diesen Typ ein:

type Name string

func (n Name) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(string(n)),
    })
}

type Person struct {
    Name Name `json:"name"`
}

Dieser Ansatz isoliert die Marshalling-Anpassung auf einen dedizierten Typ und verhindert so unerwartete Nebenwirkungen beim Einbetten der Person-Struktur an anderer Stelle.

Beispiel: https://play.golang.org/p/u96T4C6PaY

Das obige ist der detaillierte Inhalt vonWie kann ich eine Struktur mit einem benutzerdefinierten „MarshalJSON()' in Go idiomatisch einbetten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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