如果有一個簡單的值類型,那麼作爲@VonC所述,您可以使用map[string]X
並返回示例值的副本。
對於其他任何東西,而不是使用反射,我只是使用創建函數的地圖。像什麼image
包與 image.RegisterFormat
。
E.g. (playground):
package main
import "fmt"
type X interface {
y()
}
type newXFunc func() X
// Here just a map variable and two functions, but
// this could be a type with two methods instead.
var m = map[string]newXFunc{}
func register(name string, fn newXFunc) {
m[name] = fn
}
func factory(name string) X {
return m[name]()
}
func init() {
// If register is exported than these
// calls can be in other packages that
// implement A and B.
register("a", NewA)
// For simple things that don't have/need
// their own stand-alone "new" function.
register("b", func() X { return B{} })
}
type A struct{}
func (a *A) y() {}
func NewA() X { return &A{} }
type B struct{}
func (b B) y() {}
func main() {
a1 := factory("a")
b1 := factory("b")
fmt.Printf("%T\n", a1)
fmt.Printf("%T\n", b1)
}
Thanks @VonC。看起來像使用實例註冊類型的額外開銷小,但我想這個實例將被合理快速地垃圾收集? –
@ Ali-AkberSaifee是的,它會的。但總的來說,反射速度較慢,所以如果你打算每秒鐘撥打數百次的時間,地圖會更快。 – VonC
@ Ali-AkberSaifee您希望您的工廠返回A或B的* new *實例嗎?如果是的話,我已經編輯了答案。 – VonC