Heim  >  Artikel  >  Backend-Entwicklung  >  Warum gibt JSON Unmarshal bei der Arbeit mit Schnittstellen eine Map anstelle einer Struktur in Go zurück?

Warum gibt JSON Unmarshal bei der Arbeit mit Schnittstellen eine Map anstelle einer Struktur in Go zurück?

Barbara Streisand
Barbara StreisandOriginal
2024-10-25 09:26:02605Durchsuche

Why Does JSON Unmarshal Return a Map Instead of a Struct in Go When Working with Interfaces?

Das Geheimnis hinter dem JSON-Unmarshal, das eine Karte anstelle der beabsichtigten Struktur zurückgibt

JSON-Unmarshaling in Go kann beim Umgang mit Schnittstellen und Strukturen zu Herausforderungen führen. Entwickler können auf Situationen stoßen, in denen der Unmarshal-Prozess eine Karte anstelle der erwarteten Struktur liefert, wie es im folgenden Snippet der Fall ist:

<code class="go">import "encoding/json"
import "fmt"
import "reflect"

func main() {
    type Ping struct {
        ID int `json:"id"`
    }
    var ping interface{} = Ping{}
    if err := json.Unmarshal([]byte(`{"id":42}`), &ping); err != nil {
        panic(err)
    }
    fmt.Println("Unexpected:", ping) // Result: map[id:42]
}</code>

Der zugrunde liegende Grund für dieses Verhalten liegt in der abstrakten Natur von Schnittstellen. Wenn JSON-Unmarshaling für eine Schnittstelle durchgeführt wird, ist das Ergebnis eine Karte, die die Felder des zugrunde liegenden Typs darstellt. Im obigen Beispiel enthält die Schnittstelle Ping eine Karte mit einem einzelnen Schlüssel-Wert-Paar: {"id":42}.

Um dieses Problem zu beheben und die gewünschte Struktur zu erhalten, ist es wichtig, einen Zeiger zu übergeben auf den spezifischen Strukturtyp:

<code class="go">type Ping struct {
    ID int `json:"id"`
}
func main() {
    var ping Ping
    if err := json.Unmarshal([]byte(`{"id":42}`), &ping); err != nil {
        panic(err)
    }
    fmt.Println("Success:", ping) // Result: {42}
}</code>

Durch die Übergabe des Zeigers an Ping wird der JSON-Unmarshal-Prozess angewiesen, eine Instanz der Struktur zu erstellen und ihre Felder zu füllen, anstatt eine Karte zu erstellen.

Alternativ können Sie, wenn ein Zeiger auf die konkrete Struktur nicht verfügbar ist, Reflektion verwenden, um den Zeiger dynamisch zu erstellen und anschließend seinen Wert der Schnittstelle zuzuweisen:

<code class="go">import "reflect"

func main() {
    var ping interface{} = Ping{}
    nptr := reflect.New(reflect.TypeOf(ping))
    if err := json.Unmarshal([]byte(`{"id":42}`), nptr.Interface()); err != nil {
        panic(err)
    }
    ping = nptr.Elem().Interface()
    fmt.Println("Reflect-Based:", ping) // Result: {42}
}</code>

Das obige ist der detaillierte Inhalt vonWarum gibt JSON Unmarshal bei der Arbeit mit Schnittstellen eine Map anstelle einer Struktur in Go zurück?. 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