Incompréhension du type Interface{} : dévoiler les complexités
Dans Go, le type interface{} offre à la fois flexibilité et complexité. Cependant, une mauvaise compréhension de sa nature peut entraîner des conséquences inattendues, comme le montre un exemple déroutant.
Lorsque vous essayez de transmettre un type non-pointeur en tant que paramètre d'interface{} à une fonction et d'utiliser json.Unmarshal avec lui, le résultat peut être surprenant. L'exemple ci-dessous démontre ce comportement :
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{}) }
Sortie :
main.Test *interface {} map[string]interface {}
Dévoilement du mystère
La confusion vient de la nature de l'interface {}. Ce n'est pas simplement un conteneur sans type mais plutôt un wrapper pour une paire (valeur, type). L'interface stocke une référence à la valeur concrète et à son type.
json.Unmarshal prend une valeur interface{} comme entrée, nous pouvons donc lui transmettre directement i. Tenter de prendre son adresse (comme avec &i) est inutile.
Pointeurs et interfaces
Cependant, si i contient une valeur non-pointeur, json.Unmarshal fait face à un défi. Étant donné que le package ne peut pas être désorganisé en un non-pointeur, il crée une nouvelle valeur de type interface{}. Cela lui permet de choisir le type, qui est par défaut map[string]interface{}.
Le scénario correct
Pour un scénario de pointeur, passer &i comme argument fonctionne car json.Unmarshal déréférence le pointeur pour trouver la valeur interface{} contenant la valeur *Test. Le pointeur garantit que le démarshalage se produit dans le type correct.
Conclusion
Pour éviter ces confusions, évitez d'utiliser des pointeurs vers des interfaces. Au lieu de cela, "placez" les pointeurs dans les interfaces et transmettez-les directement. En comprenant l'interaction entre l'interface{} et les pointeurs, les développeurs peuvent éviter des résultats inattendus et exploiter efficacement le système de types de Go.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!