Home >Backend Development >Golang >How Can Go Function Types Returning Structs Be Used for Interface Implementations?

How Can Go Function Types Returning Structs Be Used for Interface Implementations?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-05 09:12:14977browse

How Can Go Function Types Returning Structs Be Used for Interface Implementations?

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn