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{}) }
Ausgabe:
main.Test *interface {} map[string]interface {}
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!