Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Function types that return interfaces in go

I’m trying to build a factory that constructs implementations of a given interface. To make adding new implementations of that interface easier, I’m trying to have the various implementations auto-register their constructors with the factory at init() time, but I can’t seem to figure out if it’s possible to make something like this.

Here’s a very simple thing that I thought would work, but doesn’t (from the playground: https://go.dev/play/p/D-gmcpX3_BE). It gives the error:

cannot use BarConstructor (value of type func() bar) as type FooConstructor in argument to tester

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package main

import "fmt"

// foo is an interface that just has a single function
type foo interface {
    f() string
}

// bar is a type that implements foo
type bar struct {
}

func (b bar) f() string {
    return "baz"
}

// BarConstructor creates bars
func BarConstructor() bar {
    return bar{}
}

// FooConstructor is a function type that returns foo interfaces
type FooConstructor func() foo

// take a thing that constructs foos
func tester(constructor FooConstructor) {
    f := constructor()
    fmt.Println(f.f())
}

func main() {
    // Why is BarConstructor not the right type?
    tester(BarConstructor)
}

>Solution :

BarConstructor is a function that returns bar, but the tester needs a function that returns foo. Even though bar implements foo, the signatures don’t match, so the argument is not accepted.

Go type system treats all types as distinct types based on their name/signature.

You have a few options:

  1. Declare the BarConstructor to return foo
  2. Write an adapter func:
tester(func() foo {return BarConstructor()})
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading