2013-12-10 94 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