Dans Go, un commutateur de type vous permet de faire correspondre une valeur à plusieurs types. Cependant, lors de l'utilisation de plusieurs cas dans un commutateur de type, la compréhension des affectations de types de variables devient cruciale.
Considérez l'extrait de code suivant :
package main import ( "fmt" ) type A struct { a int } func (this *A) test() { fmt.Println(this) } type B struct { A } func main() { var foo interface{} foo = A{} switch a := foo.(type) { case B, A: a.test() } }
Lors de l'exécution de ce code, une erreur est générée : a .test non défini (le type interface {} est une interface sans méthodes). Cette erreur se produit car la variable a conserve le type interface{}, malgré le changement de type.
Pour comprendre ce comportement, nous devons nous référer à la spécification Go :
"Le TypeSwitchGuard peut inclure une courte déclaration de variable. Lorsque cette forme est utilisée, la variable est déclarée au début du bloc implicite dans chaque clause. Dans les clauses avec un cas répertoriant exactement un type, la variable a ce type ; l'expression dans le TypeSwitchGuard."
Dans notre cas, puisque plusieurs types (B et A) sont spécifiés dans la clause case, la variable a conserve le type de l'expression dans le TypeSwitchGuard, qui est interface{} . Cela signifie que le compilateur ne nous permettra pas d'appeler la méthode test() sur un car interface{} n'a pas de méthode test().
Pour résoudre ce problème, nous pouvons utiliser des assertions de type, qui permettent nous pour affirmer qu’une valeur a un type spécifique. Voici une version mise à jour du code qui utilise les assertions de type :
package main import ( "fmt" ) type A struct { a int } func (this *A) test() { fmt.Println(this) } type B struct { A } func main() { var foo interface{} foo = &B{} if a, ok := foo.(tester); ok { fmt.Println("foo has test() method") a.test() } }
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!