Maison >développement back-end >Golang >Comment les types de fonctions Go renvoyant des structures peuvent-ils être utilisés pour les implémentations d'interface ?
Types de fonctions Go renvoyant des structures pour les implémentations d'interface
Considérez un scénario dans lequel vous avez une structure dans un package avec des méthodes et une usine chronophages fonction. Pour tester efficacement cette structure, il est souhaitable d'utiliser à la fois une fausse fonction d'usine et une fausse structure une fois créée.
Le code suivant illustre ceci :
package expensive import "fmt" type myStruct struct{} func (m *myStruct) DoSomething() { fmt.Println("In Do something") } func (m *myStruct) DoSomethingElse() { fmt.Println("In Do something else") } // CreateInstance is expensive to call func CreateInstance() *myStruct { return &myStruct{} }
Dans un package dépendant, nous interfaçons comme ceci :
package main import "play/expensive" func main() { thing := structToConstruct{expensive.CreateInstance} thing.performAction() } type myInterface interface { DoSomething() } type structToConstruct struct { factoryFunction func() myInterface } func (s *structToConstruct) performAction() { instance := s.factoryFunction() instance.DoSomething() }
Cependant, ce code soulève un erreur :
.\main.go:6: cannot use expensive.CreateInstance (type func() *expensive.myStruct) as type func() myInterface in field value
Malgré *expensive.myStruct implémentant myInterface, Go se plaint de la sécurité des types.
Selon l'équipe Go, ce comportement est intentionnel :
Having a function type in a struct field that returns the underlying concrete type would violate a core principle of interfaces. That principle is that the concrete type can be replaced by any other implementation of the interface type. If the receiver type of a function were the underlying concrete type, the behavior of the function would change if called via an interface.
La solution est d'envelopper la fonction d'usine :
wrapper := func() myInterface { return expensive.CreateInstance() } thing := structToConstruct{wrapper}
Ce wrapper adhère à myInterface et le code se compile.
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!