我有以下两种类型:
type Routing map[string]Handler
type Handler interface {
Handle()
}
我有一个名为MyHandler
的类型,它满足界面,它看起来像这样:
type MyHandler struct {
}
func (this *MyHandler) Handle() {
// ...
}
我希望能够做到这样的事情:
// routes is created at the beginning of the program and available
// throughout the lifetime of the script
routes := Routing {
"/route/here": MyHandler,
})
// ...
// and in another method, this line may be executed several times:
new(routes["/route/here"]).Handle()
我在最后一行收到此错误:
routes [“/ route / here”]不是类型
当我将最后一行更改为
时routes["/route/here"].Handle()
它显然有效。但是,它只使用Handler的一个实例...我希望每次执行最后一行时都有一个新实例。如何在每次执行最后一行时实例化Handler
的新实例?
(我假设在使用new
时,旧的将在使用后被垃圾收集。请注意,我没有保存我创建的实例;我只关心调用Handle()
方法然后将其销毁。)
答案 0 :(得分:5)
new()
将类型作为参数,并返回指向该类型的清零值的指针。类型不是Go中的第一类值。 New是内置的,因此它不会遵循其他代码所遵循的相同规则。新的需要在编译时知道它将处理什么类型。无法构建类型的地图。
我的建议是使用函数来构建每种类型。
type Routing map[string]func() Handler
routes := Routing {
"/route/here": func() Handler { return new(MyHandler)},
}
routes["/route/here"]().Handle()
我们正在构建一个返回所需类型的函数映射,而不是构建类型映射。
另一种可能性是使用反射虽然我更喜欢上面的功能方法。对于这个用例,我认为这将是一种滥用反射。
type Routing map[string]reflect.Type
routes := Routing {
"/route/here": reflect.TypeOf(MyHandler{}),
}
reflect.New(routes["/route/here"]).Interface().(Handler).Handle()
警告,如果MyHandler没有实现Handler,这将使程序崩溃。这种方法放弃了编译时类型检查。