创建构造函数图

So I'd like to have a map of names of functions, to choose an implementation of an interface based on an environment variable. I've reproduced it in the following code:

package test

type Fooer interface {
    Foo() error
}

type Bar struct{}

func NewBar() (*Bar, error) { return &Bar{}, nil }
func (b *Bar) Foo() error   { return nil }

type Baz struct{}

func NewBaz() (*Baz, error) { return &Baz{}, nil }
func (b *Baz) Foo() error   { return nil }

var constructors map[string]func() (*Fooer, error)

func init() {
    constructors = map[string]func() (*Fooer, error){
        "bar": NewBar,
        "baz": NewBaz,
    }
}

This throws the following errors when I go build test.go:

./test.go:21: cannot use NewBar (type func() (*Bar, error)) as type func() (*Fooer, error) in map value
./test.go:22: cannot use NewBaz (type func() (*Baz, error)) as type func() (*Fooer, error) in map value

So what am I doing wrong? Can I use a *Fooer as the return type of a constructor function? What would be the actual best way to approach this? (I'm new to Go)

  1. Do not (almost never) pass around pointers to interface. You will (almost) never need a *Fooer, a Fooer is enough.
  2. Yes, your Bar and Baz constructors could return a Fooer (not a *Fooer!) but that seems awkward.
  3. Keeping the constructors in a map and querying the map for a constructor seem like one level of indirection too much. Are you constantly creating new Bar and Baz?