我是一个新人,我几乎整天都在与这个问题作斗争。
考虑到我有这些:
type HandlerType func()
var object interface{}
var typedObject HandlerType
我可以为typedObject变量分配一个函数,如下所示:
typedHandler = func() {
fmt.Println("in a handler!\n")
}
但我需要做的是将该处理函数作为接口{}变量传递,然后以某种方式将其转换为HandlerType,稍后我可以调用它
我已经尝试了这个,但它引发了一个错误:
typedHandler = object.(HandlerType)
结果:
接口转换:接口是func(),而不是main.HandlerType
基本上我需要在注册之前注册具有不同签名的函数而无需额外的类型转换。所以不要这样做:
registerHandler(HandlerTypeString(func() string { ... }))
registerHandler(HandlerTypeVoid(func() { ... }))
我想注册这样的处理程序:
registerHandler(func() string { ... })
registerHandler(func() { ... })
..而且我不希望在稍后处理程序调用时涉及反射
有可能吗?
修改:我创建了一个游乐场:http://play.golang.org/p/UlwqkHjt_P
据我了解,没有办法将一些任意函数作为 interface {} 传递,然后以某种方式将其转换为HandlerType或其他一些预定义的函数类型,这样我就可以不使用它来调用它反射?
Edit2 :我已经提出了这个解决方案:http://play.golang.org/p/4gUxsgmiPf
使用此代码在运行时期间不应该有任何性能损失。但是,有人可以在没有接口{} 的情况下想出实现此功能的另一种方法吗?
答案 0 :(得分:8)
您不能使用object.(func())
,object.(func() string)
等等。
func main() {
type HandlerType func()
var object interface{} = func() {
fmt.Println("eureka!")
}
if f, ok := object.(func()); ok {
HandlerType(f)()
}
}
答案 1 :(得分:8)
你的问题中存在一些小的误解:
类型断言不用于转换类型。它只是检查变量是否为给定类型并将变量作为此基础类型返回。此操作会在您的情况下返回错误,这是正常的,因为func()
不是HandlerFunc
类型。
您不需要做任何事情来将变量作为参数传递给接受interface{}
的函数。每种类型都隐式实现空接口。
即使func()
由HandlerType
定义,HandlerType
也不是type HandlerType func()
。该定义与此无关。
你想做的事情是不可能的。我不是反思专家,但我不认为反思可以解决你的问题。
也就是说,您的注册方法应该定义所有注册对象应该实现的接口,并将此接口用作参数类型。请查看database/sql
包Register
方法以获取示例。
答案 2 :(得分:0)
您现在可以使用reflect.MakeFunc执行此操作。有关于如何操作的示例