„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Wie kann ich JSON mit generischen Typen in Go 1.18 sicher entmarshalieren?

Wie kann ich JSON mit generischen Typen in Go 1.18 sicher entmarshalieren?

Veröffentlicht am 07.11.2024
Durchsuche:972

How Can I Safely Unmarshal JSON with Generic Types in Go 1.18?

Generische Verwendung in Unmarshal (Go 1.18)

Bei der Verwendung von Generika in Go 1.18, z. B. beim Erstellen eines Containers zur Aufnahme verschiedener Berichtstypen, Typbeschränkungen können auftreten. Betrachten Sie das folgende Setup:

  • Mehrere Berichtstypen, dargestellt durch Strukturen
  • Ein ReportContainer-Wrapper mit einem generischen Typparameter Reportable, eingeschränkt auf die Implementierung der Reportable-Schnittstelle
  • Ein Diskriminator ReportType zum Bestimmen des konkreten Berichtstyps während des Unmarshallings

Es können Probleme mit Typeinschränkungen für Rückgabetypen auftreten, die zu „Freitextsemantik“ in der GetBody()-Funktion führen, um die Typzusicherung zu berücksichtigen.

Herausforderungen und Lösungen

Das Problem ist darauf zurückzuführen, dass Go Typzusicherungen für Strukturen nicht unterstützt und keine Zeiger auf generische Typen zulässt. Um dieses Problem zu beheben, können Sie eine Schnittstelle erstellen, die Getter für LocationID, Provider, ReportType und Body implementiert. Diese Lösung erfordert jedoch Einbußen bei der Typsicherheit.

Ein sichererer Ansatz besteht darin, auf parametrischen Polymorphismus zu verzichten und beim JSON-Unmarshalling eine konkrete Switch-Anweisung zu verwenden, die auf dem Diskriminatorwert basiert. Dadurch wird sichergestellt, dass für jeden Berichtstyp der richtige konkrete Typ verwendet wird.

Alternativer Ansatz

Für die dynamische JSON-Analyse können Sie eine generische Unmarshal-Funktion verwenden:

func unmarshalAny[T any](bytes []byte) (*T, error) {
    out := new(T)
    if err := json.Unmarshal(bytes, out); err != nil {
        return nil, err
    }
    return out, nil
}

Obwohl diese Funktion Flexibilität bietet, ist es wichtig zu beachten, dass sie bei minimaler Implementierung lediglich die gleichen Aktionen ausführt wie das direkte Inlining der Unmarshalling-Logik. Daher ist die Verwendung dieser Funktion nur dann gerechtfertigt, wenn sie zusätzliche Logik einführt.

Zusammenfassend sollten Sie sorgfältig die Notwendigkeit von Generika berücksichtigen, wenn Sie mit konkreten Typen und JSON-Unmarshalling arbeiten. Entscheiden Sie sich bei Bedarf für eine schalterbasierte Lösung, ohne die Typsicherheit zu beeinträchtigen, und seien Sie vorsichtig, wenn Sie generische Funktionen verwenden, die die Funktionalität unnötig duplizieren.

Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3