Sorry, I post my question again.
I have been read the solution before I ask my question. I think it can not help me because my question is how to pass a function as a parameter? I don't want to call it.
I just want to pass it to another function that I can't edit (or I don't want to edit), and I want to use a string variable to point the function
funcName := "Go"
m.set(t.funcName)
I think this is different from this question Call a Struct and its Method by name in Go?
for example
I have a function like:
type Context struct{}
type myclass struct{}
type Handler func (c *Context)
func (r *myclass) set(ch Handler) {
}
I can use this way:
type testclass struct {}
func (t *testclass) Go(c *Context){
println("Hello");
}
t := &testclass{}
m := &myclass{}
m.set(t.Go)
and my question is
type testclass struct{}
func (t *testclass) Go(c *Context){
println("Hello");
}
t := &testclass{}
m := &myclass{}
funcName := "Go"
m.set(t.funcName)
any way can do this?
reflect?or what?
if it is impossible, there are other ways to do this?
thanks
You can get the method by name using the reflect package. Here's a function to get a Handler
given the name:
func handlerByName(v interface{}, name string) (Handler, error) {
m := reflect.ValueOf(v).MethodByName(name)
if !m.IsValid() {
return nil, errors.New("method not found")
}
h, ok := m.Interface().(func(*Context))
if !ok {
return nil, errors.New("method is not a handler")
}
return h, nil
}
Here's how to use the function:
h, err := handlerByName(t, "Go")
if err != nil {
// handle error
}
m.set(h)
Note that the function returned by handlerByName is a reflection wrapper around the original function (thanks @OneOfOne for pointing this out). Calling the wrapper is slow compared to calling the function directly.