Heim > Backend-Entwicklung > Golang > Warum führt „json.Unmarshal' mit einem Nicht-Zeiger-Parameter „interface{}' zu unerwarteten Ergebnissen in Go?

Warum führt „json.Unmarshal' mit einem Nicht-Zeiger-Parameter „interface{}' zu unerwarteten Ergebnissen in Go?

Mary-Kate Olsen
Freigeben: 2024-12-04 20:19:12
Original
272 Leute haben es durchsucht

Why Does `json.Unmarshal` with a Non-Pointer `interface{}` Parameter Produce Unexpected Results in Go?

Missverständnis des Interface{}-Typs: Die Komplexität aufdecken

In Go bietet der Interface{}-Typ sowohl Flexibilität als auch Komplexität. Ein Missverständnis seiner Natur kann jedoch zu unerwarteten Konsequenzen führen, wie ein rätselhaftes Beispiel zeigt.

Wenn Sie versuchen, einen Nicht-Zeigertyp als Schnittstellenparameter{} an eine Funktion zu übergeben und json.Unmarshal damit zu verwenden, Die Ausgabe kann überraschend sein. Das folgende Beispiel zeigt dieses Verhalten:

package main

import (
    "encoding/json"
    "fmt"
)

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, &i)
    fmt.Printf("%T\n", i)
}

type Test struct {
    Foo string
}

func main() {
    test(Test{})
}
Nach dem Login kopieren

Ausgabe:

main.Test
*interface {}
map[string]interface {}
Nach dem Login kopieren

Enthüllung des Geheimnisses

Die Verwirrung ergibt sich aus der Natur der Schnittstelle {}. Es handelt sich nicht einfach um einen typlosen Container, sondern vielmehr um einen Wrapper für ein (Wert-, Typ-)Paar. Die Schnittstelle speichert einen Verweis auf den konkreten Wert und seinen Typ.

json.Unmarshal verwendet einen Interface{}-Wert als Eingabe, sodass wir i direkt daran übergeben können. Der Versuch, seine Adresse zu übernehmen (wie bei &i), ist unnötig.

Zeiger und Schnittstellen

Wenn i jedoch einen Nicht-Zeigerwert enthält, sieht sich json.Unmarshal einem gegenüber Herausforderung. Da das Paket nicht in einen Nicht-Zeiger entmarshallt werden kann, erstellt es einen neuen Wert vom Typ interface{}. Dadurch kann der Typ ausgewählt werden, der standardmäßig „map[string]interface{}“ ist.

Das richtige Szenario

Für ein Zeigerszenario wird &i als Argument übergeben funktioniert, weil json.Unmarshal den Zeiger dereferenziert, um den interface{}-Wert zu finden, der den *Test-Wert enthält. Der Zeiger stellt sicher, dass das Unmarshaling in den richtigen Typ erfolgt.

Fazit

Um diese Verwirrungen zu vermeiden, verzichten Sie auf die Verwendung von Zeigern auf Schnittstellen. Platzieren Sie stattdessen Zeiger innerhalb der Schnittstellen und geben Sie sie direkt weiter. Durch das Verständnis des Zusammenspiels zwischen Schnittstelle{} und Zeigern können Entwickler unerwartete Ergebnisse vermeiden und das Typsystem von Go effektiv nutzen.

Das obige ist der detaillierte Inhalt vonWarum führt „json.Unmarshal' mit einem Nicht-Zeiger-Parameter „interface{}' zu unerwarteten Ergebnissen in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage