Maison > Article > développement back-end > Pourquoi les appels d’interface dans mon programme Go échouent-ils ?
Le langage Go est devenu l'un des langages de programmation les plus populaires au monde en raison de ses caractéristiques rapides et efficaces. L'interface est une fonctionnalité puissante du langage Go, qui offre aux programmeurs un moyen très élégant d'interagir et de communiquer entre différentes structures. Cependant, lorsque les appels d’interface échouent, il s’agit d’un problème courant pour certains programmeurs débutants. Cet article explorera les raisons pour lesquelles les appels d’interface échouent et proposera des solutions.
En langage Go, lorsque les données sont généralement transmises à une fonction, les données seront copiées dans les paramètres de la fonction. Et lorsque nous passons l'interface en paramètre à la fonction, si la valeur du type d'interface n'est pas un type pointeur, elle sera copiée en tant que type valeur. Cela peut entraîner l’échec des appels d’interface dans certains cas.
L'appel d'interface est obtenu en appelant la méthode de la valeur d'interface, et cela nécessite que le type de valeur d'interface soit un type de pointeur, car la méthode doit opérer sur le pointeur. Si nous attribuons une valeur de type non-pointeur à une interface, le langage Go copiera les données internes et créera une nouvelle valeur d'interface. Mais cette nouvelle valeur d’interface ne sera plus un type pointeur, nous ne pouvons donc pas appeler directement des méthodes sur cette nouvelle valeur d’interface. C'est pourquoi l'appel d'interface échoue.
Donc, si nous voulons appeler des interfaces et nous assurer qu'elles fonctionnent correctement, nous devons alors nous assurer que la valeur du type d'interface est un type pointeur.
En langage Go, si une variable n'est pas un type d'interface, alors elle ne peut pas être affectée à un type d'interface. En effet, l'interface est de type dynamique et ne peut pas être vérifiée par le compilateur. Si les types d’interface ne correspondent pas, l’appel d’interface échouera également. Regardez l'exemple suivant :
type Employee struct { Name string Age int } func (e Employee) ShowName() { fmt.Printf("Name is %s ", e.Name) } func showName(s interface{}) { s.ShowName() } func main() { emp := Employee{Name: "John", Age: 25} showName(emp) }
Le code ci-dessus générera l'erreur suivante :
cannot use emp (type Employee) as type interface {} in argument to showName: Employee does not implement interface {} (missing ShowName method)
Le compilateur Go pensera que ce type d'employé est un type différent, il ne peut donc pas être directement affecté à une variable de type interface{}. Pour résoudre ce problème, nous pouvons modifier le type Employee pour implémenter l'interface dont il a besoin afin de pouvoir le transmettre en paramètre à la fonction showName.
Un autre échec d'appel d'interface courant est l'implémentation incomplète de l'interface. En bref, cela signifie que nous implémentons une interface sur un type struct, mais n'implémentons pas toutes les méthodes de l'interface. Cela peut provoquer des échecs lors des appels d'interface. Regardez l'exemple ci-dessous :
type Square struct { Side int } func (s Square) Area() int { return s.Side * s.Side } type Shape interface { Area() int } func PrintArea(s Shape) { fmt.Println("Area is", s.Area()) } func main() { sq := Square{Side: 5} PrintArea(sq) }
Le code ci-dessus produira l'erreur suivante :
cannot use sq (type Square) as type Shape in argument to PrintArea: Square does not implement Shape (missing Area method)
Dans cet exemple, nous avons défini un type Square et une interface Shape. Nous avons implémenté la méthode Area sur le type Square. Mais nous n'implémentons pas d'autres méthodes de l'interface Shape. Cela entraîne l’échec des appels d’interface dans la fonction PrintArea. Par conséquent, assurez-vous que toutes les méthodes de l'interface sont implémentées sur le type spécifié afin que l'appel d'interface puisse réussir.
En langage Go, des valeurs nulles peuvent être attribuées aux interfaces. Cela signifie que dans une interface, nous pouvons transmettre une valeur nulle comme valeur valide. Cependant, cela peut également entraîner l’échec de l’appel d’interface.
Lorsque la valeur de l'interface est nulle, l'appel de méthodes dessus provoquera une erreur d'exécution. Regardez l'exemple suivant :
type Calculator interface { Add(a int, b int) int } func main() { var c Calculator fmt.Println(c.Add(1, 2)) }
Le code ci-dessus générera l'erreur suivante :
panic: runtime error: invalid memory address or nil pointer dereference
La solution est qu'avant d'utiliser une interface avec une valeur nulle, nous devons nous assurer que le type d'interface a été entièrement implémenté, ou vous pouvez utilisez une assertion de type pour déterminer que l'interface n'est pas une valeur nulle.
func main() { var c Calculator if c != nil { fmt.Println(c.Add(1, 2)) } }
Dans le langage Go, lorsque nous attribuons une valeur de type non-pointeur à l'interface, Go copiera les données internes et créera une nouvelle valeur d'interface. Cette nouvelle valeur d'interface est également une interface différente avec la même valeur. Par conséquent, lorsque nous appelons une méthode dans une interface, nous devons effectuer l’appel de méthode en dehors de l’interface avec une valeur de type primitif ou un type pointeur vers une valeur primitive.
Regardez l'exemple suivant :
type Employee struct { Name string Age int } func (e Employee) ShowName() { fmt.Printf("Name is %s ", e.Name) } type NameShower interface { ShowName() } func main() { emp := Employee{Name: "John", Age: 25} var ns NameShower ns = emp ns.ShowName() pemp := &Employee{Name: "Doe", Age: 30} ns = pemp ns.ShowName() }
Dans le code ci-dessus, nous définissons un type Employee et une interface NameShower. Lorsque nous créons emp et l'attribuons à ns, l'appel d'interface échouera car emp n'est pas un type pointeur vers une valeur primitive. Nous devons utiliser un pointeur vers emp pour appeler la méthode ShowName.
Lors de la création de pemp et de son attribution à ns, l'appel d'interface réussira car pemp est un type pointeur vers une valeur primitive. Assurez-vous donc que nous avons utilisé le bon type avant de passer un appel d’interface.
Conclusion
A travers cet article, nous connaissons déjà les raisons pour lesquelles les appels d'interface échouent dans les programmes Go. Ensuite, résumons :
Si vous suivez la méthode ci-dessus, l'appel d'interface dans votre programme Go n'échouera pas.
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!