Go Function Types Returning Structs for Interface Implementations
Consider a scenario where you have a struct in a package with time-consuming methods and factory function. To test this struct effectively, it's desirable to utilize both a fake factory function and a fake struct once created.
The following code exemplifies this:
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{} }
In a dependent package, we interface like this:
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() }
However, this code raises an error:
.\main.go:6: cannot use expensive.CreateInstance (type func() *expensive.myStruct) as type func() myInterface in field value
Despite *expensive.myStruct implementing the myInterface, Go complains about type safety.
According to the Go team, this behavior is intentional:
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.
The solution is to wrap the factory function:
wrapper := func() myInterface { return expensive.CreateInstance() } thing := structToConstruct{wrapper}
This wrapper adheres to the myInterface and the code compiles.
The above is the detailed content of How Can Go Function Types Returning Structs Be Used for Interface Implementations?. For more information, please follow other related articles on the PHP Chinese website!