如果有一个简单的值类型,那么作为@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