-1

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

Community
  • 1
  • 1
herb
  • 45
  • 1
  • 5

1 Answers1

0

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)

playground example

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.

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • You should add that this isn't very idiomatic (or safe) code. The OP's code could probably avoid this if we had more context around the "why". – elithrar Mar 07 '16 at 08:15
  • The OP presumably is not an advanced Go user. Why do you recommend using reflection? – Volker Mar 07 '16 at 09:37
  • @Volker The suitability of reflection for a given task is independent of the person asking. – Charlie Tumahai Mar 07 '16 at 13:51
  • @elithrar I updated the code to make it safe. Thanks for the feedback. – Charlie Tumahai Mar 07 '16 at 13:53
  • Also note that using reflection to call methods/funcs is extremely slow because of the added wrappers. – OneOfOne Mar 07 '16 at 14:14
  • @OneOfOne Reflection does not add any wrappers around the function returned from `handlerByName`. There is a cost to finding the function using reflection, but that cost is not extreme compared to other possible ways to find a function given a string. – Charlie Tumahai Mar 07 '16 at 14:34
  • @OneOfOne Thank you for that. Do you know where in the reflect code the wrapper is added? – Charlie Tumahai Mar 07 '16 at 14:50
  • @Volker yes, I just study golang about few days, you may think Im not qualified enough but I just want to write a web framework for myself, I know this is not a easy work but I will try my best – herb Mar 08 '16 at 02:15