Heim >Backend-Entwicklung >Golang >Wie kann ich inkonsistente JSON-Felder, die manchmal Strings und manchmal Arrays von Strings sind, in Go effizient entmarshalieren?

Wie kann ich inkonsistente JSON-Felder, die manchmal Strings und manchmal Arrays von Strings sind, in Go effizient entmarshalieren?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-22 01:21:15482Durchsuche

How Can I Efficiently Unmarshal Inconsistent JSON Fields That Are Sometimes Strings and Sometimes Arrays of Strings in Go?

Inkonsistente JSON-Feldverarbeitung: Unmarshaling als String oder Array

Bei der Arbeit mit JSON-Daten, die Inkonsistenzen aufweisen, kann das Unmarshaling eine Herausforderung darstellen Felder, deren Typ variieren kann, z. B. entweder eine Zeichenfolge oder ein Array von Zeichenfolgen. Dieser Artikel befasst sich mit diesem Problem und bietet praktische Lösungen.

Das Problem

Betrachten Sie die folgende JSON-Struktur, bei der das Feld „display_name“ entweder eine Zeichenfolge oder ein Array von Zeichenfolgen ist :

{
    "date": "30 Apr",
    "display_name": "Mr Smith"
},
{
    "date": "30 Apr",
    "display_name": ["Mr Smith", "Mr Jones"],
}

Der Versuch, diese Daten mit den folgenden Go-Strukturen zu entmarshalieren, führt zu einem Fehler:

type MyListItem struct {
    Date  string `json:"date"`
    DisplayName       string `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}

Lösung

Um diese Herausforderung zu meistern, kann man die Vielseitigkeit von json.RawMessage nutzen, das die Erfassung unterschiedlicher Felddaten ermöglicht. Darüber hinaus kann der Feldname „-“ verwendet werden, um das Feld „DisplayName“ vor dem Decoder auszublenden, sodass die Anwendung es füllen kann, nachdem der JSON der obersten Ebene dekodiert wurde.

Geänderte Go-Struktur

type MyListItem struct {
    Date           string          `json:"date"`
    RawDisplayName json.RawMessage `json:"display_name"`
    DisplayName    []string        `json:"-"`
}

Unmarshaling-Prozess

Unmarshaling der JSON der obersten Ebene:

var li MyListItem
if err := json.Unmarshal(data, &li); err != nil {
    // handle error
}

Rekonstruktion des Felds „display_name“ basierend auf dem Typ der Rohdaten:

if len(li.RawDisplayName) > 0 {
    switch li.RawDisplayName[0] {
    case '"':
        if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil {
            // handle error
        }
    case '[':
        var s []string
        if err := json.Unmarshal(li.RawDisplayName, &s); err != nil {
            // handle error
        }
        // Join arrays with "&&" per OP's comment on the question.
        li.DisplayName = strings.Join(s, "&&")
    }
}

Bei mehreren Vorkommen dieses inkonsistenten Felds innerhalb eines Datenmodells a Benutzerdefinierter Typ und Implementierung der json.Unmarshaler-Schnittstelle können verwendet werden, um die Logik zu kapseln.

Benutzerdefiniert Unmarshaler

type multiString string

func (ms *multiString) UnmarshalJSON(data []byte) error {
    if len(data) > 0 {
        switch data[0] {
        case '"':
            var s string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(s)
        case '[':
            var s []string
            if err := json.Unmarshal(data, &s); err != nil {
                return err
            }
            *ms = multiString(strings.Join(s, "&&"))
        }
    }
    return nil
}

Verwendung mit benutzerdefiniertem Unmarshaler

type MyListItem struct {
    Date        string      `json:"date"`
    DisplayName multiString `json:"display_name"`
}

type MyListings struct {
    CLItems []MyListItem `json:"myitems"`
}

var listings MyListings
if err := json.Unmarshal([]byte(data), &listings); err != nil {
    log.Fatal(err)
}

Diese Lösungen bieten einen umfassenden Ansatz zur effizienten Handhabung inkonsistenter JSON-Felder und ermöglichen eine flexible Zuordnung zwischen Datenstrukturen und JSON-Darstellungen.

Das obige ist der detaillierte Inhalt vonWie kann ich inkonsistente JSON-Felder, die manchmal Strings und manchmal Arrays von Strings sind, in Go effizient entmarshalieren?. 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