Heim >Backend-Entwicklung >Golang >Wie entmarshaliere ich dynamisches JSON in Go ohne generische Platzhalterfelder?

Wie entmarshaliere ich dynamisches JSON in Go ohne generische Platzhalterfelder?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-12 11:39:12934Durchsuche

How to Unmarshal Dynamic JSON in Go without Generic Placeholder Fields?

Unmarshalling von dynamischem JSON basierend auf einem Typschlüssel

Einführung

Das Unmarshalling von JSON-Daten in eine Go-Struktur kann eine unkomplizierte Aufgabe sein. Beim Umgang mit JSON-Dokumenten, die dynamische Datenstrukturen enthalten und bei denen der Feldtyp variieren kann, kann der Prozess jedoch komplexer werden. In diesem Artikel wird eine Lösung für diese Herausforderung untersucht, ohne generische Platzhalterfelder einzuführen.

Problemdefinition

Berücksichtigen Sie die folgende JSON-Spezifikation:

{
  "some_data": "foo",
  "dynamic_field": { "type": "A", "name": "Johnny" },
  "other_data": "bar"
}
{
  "some_data": "foo",
  "dynamic_field": { "type": "B", "address": "Somewhere" },
  "other_data": "bar"
}

Beide JSON-Dokumente sollten in die gleiche Go-Struktur entmarshallt werden:

type BigStruct struct {
  SomeData     string    `json:"some_data"`
  DynamicField Something `json:"dynamic_field"`
  OtherData    string    `json:"other_data"`
}

Die Schlüsselfrage ist: Wie erstellt man den Typ „Something“ und die Unmarshalling-Logik implementieren?

Lösung: Verwenden einer Schnittstelle mit der benutzerdefinierten UnmarshalJSON-Methode

Die Lösung umfasst das Erstellen einer Schnittstelle für den Typ „Something“:

type Something interface {
  GetType() string
}

Als nächstes definieren Sie spezifisch Strukturtypen, die die Something-Schnittstelle implementieren:

type BaseDynamicType struct {
  Type string `json:"type"`
}

type DynamicTypeA struct {
  BaseDynamicType
  Name string `json:"name"`
}

type DynamicTypeB struct {
  BaseDynamicType
  Address string `json:"address"`
}

Die DynamicType-Schnittstellenmethode ermöglicht die Erstellung von JSON-Daten in die entsprechende Struktur entmarshallt:

func (d *DynamicType) UnmarshalJSON(data []byte) error {
    var typ struct {
        Type string `json:"type"`
    }
    if err := json.Unmarshal(data, &typ); err != nil {
        return err
    }
    switch typ.Type {
    case "A":
        d.Value = new(TypeA)
    case "B":
        d.Value = new(TypeB)
    }
    return json.Unmarshal(data, d.Value)
}

Diese Methode überprüft die JSON-Daten und erstellt nach Bedarf eine Instanz von TypeA oder TypeB.

Implementierung von UnmarshalJSON auf der BigStruct

Endlich , implementieren Sie die UnmarshalJSON-Methode auf der BigStruct Typ:

func (b *BigStruct) UnmarshalJSON(data []byte) error {
    var tmp BigStruct // avoids infinite recursion
    return json.Unmarshal(data, &tmp)
}

Diese Methode verwendet einen temporären BigStruct-Typ, um eine Rekursion zu vermeiden, und ermöglicht das Demarshalling des dynamischen Felds mithilfe des entsprechenden DynamicType-Typs basierend auf dem Typfeld in den JSON-Daten.

Fazit

Diese Lösung bietet eine saubere und effiziente Möglichkeit, dynamische JSON-Daten zu entmarshalieren, ohne dass zusätzliche generische Platzhalterfelder erforderlich sind. Durch den Einsatz einer Schnittstelle und die Implementierung benutzerdefinierter UnmarshalJSON-Methoden kann sich die Go-Struktur an die dynamische Datenstruktur in der JSON-Eingabe anpassen.

Das obige ist der detaillierte Inhalt vonWie entmarshaliere ich dynamisches JSON in Go ohne generische Platzhalterfelder?. 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