2013-12-10 95 views
2

所以我想要有一个函数名称的映射来选择基于环境变量的接口的实现。我在下面的代码复制它:创建构造函数的地图

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, 
    } 
} 

这将引发以下错误,当我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 

那我做错了吗?我可以使用*Fooer作为构造函数的返回类型吗? 实际什么是最好的方法来解决这个问题? (我是新来的GO)

回答

2
  1. 不要(几乎没有)绕过指针接口。你将(几乎)不需要*FooerFooer就足够了。
  2. 是的,您的Bar和Baz构造函数可能会返回Fooer(不是*Fooer!),但看起来很尴尬。
  3. 保持构造函数在地图中并查询构造函数的地图看起来像太过于间接的一个级别。你是否在不断创建新的Bar和Baz?
+0

重新3:只是一次,而我设置服务器的配置。需要选择使用哪个存储实施。 –

+0

另外,我修改它不返回一个指针,我得到相同的错误(模块指针,显然。)我错过了什么? –

+1

比一个简单的'var storage Fooer;如果init中的environmentWantsBaz {storage,_ = Baz {}} else {storage,_ = Bar {}}'应该这样做。 – Volker