I'm a Go newcomer and I've been battling with this problem almost all day today.
Considering I have these:
type HandlerType func()
var object interface{}
var typedObject HandlerType
I can assign a function to the typedObject variable like this:
typedHandler = func() {
fmt.Println("in a handler!\n")
}
But what I need to do is to pass that handler function as an interface{} variable and then convert it somehow to HandlerType which I could call later
I've tried this but it throws an error:
typedHandler = object.(HandlerType)
results in:
interface conversion: interface is func(), not main.HandlerType
Basically I need to register functions with different signatures without additional type conversion before registering. So instead of doing this:
registerHandler(HandlerTypeString(func() string { ... }))
registerHandler(HandlerTypeVoid(func() { ... }))
I want to register handlers like this:
registerHandler(func() string { ... })
registerHandler(func() { ... })
.. and I don't want to involve reflection at the time of a handler call later
Is it possible?
Edit: I've created a playground: http://play.golang.org/p/UlwqkHjt_P
So as I understand there is no way to pass some arbitrary function as interface{} and then somehow convert it to HandlerType or some other predefined function type so I would be able to call it without using reflection?
Edit2: I've came up with this solution: http://play.golang.org/p/4gUxsgmiPf
There shouldn't be any performance penalties during runtime with this code. But can somebody think out another way of implementing this functionality without interface{} ?
You can't, it's a different type, you could just use object.(func())
, object.(func() string)
, etc.
func main() {
type HandlerType func()
var object interface{} = func() {
fmt.Println("eureka!")
}
if f, ok := object.(func()); ok {
HandlerType(f)()
}
}
There is a number of small misconceptions in your question:
Type assertion isn't used to cast types. All it do is checking that a variable is of the given type and returning the variable as this underlying type. This operation return a error in your case, which is normal given that func()
isn't the type HandlerFunc
.
You don't need to do anything to pass a variable as parameter in a function accepting interface{}
. Every type implicitly implement the empty interface.
A func()
isn't a HandlerType
, even if HandlerType
is defined by type HandlerType func()
. The definition has nothing to do with that.
What you want to do isn't possible. I'm not an expert with reflection, but I don't think that reflection could solve your problem either.
That said, your registering method should define a interface that all registered objects should implement, and use this interface as parameter type. Look at the database/sql
package Register
method for an example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With