3

Suppose I have two package like

-a

-b

a have some methods like this

 func TestOne() { //something }
 func TestTwo() { //something }

I need to call package a's methods from package b but by only string method name. Like i get the string "TestOne" and calls for the method TestOne(). How can i get that done.

Edit : I have Read about reflect. but reflect needs an struct and functions be a member of that struct. What if My functions are not member of a struct? just plain methods in a package. and the calling methods and called methods are in different package. Then?

NB. There could be some methods that have parameters as well.

6
  • 4
    Related / possible duplicate of Golang: pointer to function from string (function's name) Commented Oct 8, 2015 at 4:47
  • @icza I read that qustion and answer. But their solution which they said to use reflect. And reflect needs an struct and functions be a member of that struct. What if My functions are not member of a struct? just plain methods in a package. and the calling methods and called methods are in different package. Then? Commented Oct 8, 2015 at 6:45
  • Then the answer is no, you can't do that without something like a pre-populated name-function map as seen in @LightWeight's answer. Commented Oct 8, 2015 at 8:46
  • @eror Read mnagel's answer to the linked question. It should be the second answer from the top at this time. You can use reflect to call functions as long as you have the function's handle, which you can get via a map. You're misinterpreting the fact that you cannot get a free function's handle solely via reflection. As long as you build a map[string]interface{} that returns the functions by name yourself, you can call the function via reflect.ValueOf followed by Value.Call or Value.CallSlice Commented Oct 8, 2015 at 12:42
  • @Jsor Thanx, brother. I resolved it with a map you specified. :) But still in my idiot mind one question is Present - if i dont have a map how can i do it. Commented Oct 9, 2015 at 6:04

2 Answers 2

6

Like LightWeight said in his answer, you can use reflection.

You use the reflect.ValueOf method to get the value of the type. Then you can use the MethodByName method to get the function value. Once you have the function value you can call the Call method to execute it.

Code Sample

package main

import (
    "fmt"
    "reflect"
)

type TypeOne struct {
}

func (t *TypeOne) FuncOne() {
    fmt.Println("FuncOne")
}

func (t *TypeOne) FuncTwo(name string) {
    fmt.Println("Hello", name)
}

func CallFuncByName(myClass interface{}, funcName string, params ...interface{}) (out []reflect.Value, err error) {
    myClassValue := reflect.ValueOf(myClass)
    m := myClassValue.MethodByName(funcName)
    if !m.IsValid() {
        return make([]reflect.Value, 0), fmt.Errorf("Method not found \"%s\"", funcName)
    }
    in := make([]reflect.Value, len(params))
    for i, param := range params {
        in[i] = reflect.ValueOf(param)
    }
    out = m.Call(in)
    return
}

func main() {
    t1 := &TypeOne{}
    out, err := CallFuncByName(t1, "FuncOne")
    if err != nil {
        panic(err)
    }
    //Return value
    _ = out
    out, err = CallFuncByName(t1, "FuncTwo", "monkey")
    if err != nil {
        panic(err)
    }
    //Return value
    _ = out
}
Sign up to request clarification or add additional context in comments.

4 Comments

reflect needs an struct and functions be a member of that struct. What if My functions are not member of a struct? just plain methods in a package. and the calling methods and called methods are in different package. Then?
Yeah, I'm an idiot :) I knew that when I was looking at it. There is no way to directly get the package functions. You can create a map of all the functions you would want to call. funcMap := map[string]interface{}{"TestOne":TestOne,"TestTwo":TestTwo} and then use reflect.ValueOf(funcMap["TestOne"]).Call() to execute it as in the Sample Code above.
why will u be an idiot, brother. I am the one here who asks stupid questions. :P :P thank though. Trying what you just described.
@monkey_p Finally a solution which does what was asked. funcMap := map[string]interface{} way described in the comment is the right way to call methods not part of a struct IMO.
1

You can try to use reflect in go. This link may be help you https://golang.org/pkg/reflect/ and http://mikespook.com/2012/07/function-call-by-name-in-golang/

func foo() {
    // bla...bla...bla...
}
func bar(a, b, c int) {
    // bla...bla...bla...
}
funcs := map[string]interface{}{"foo":foo, "bar":bar}

1 Comment

reflect needs an struct and functions be a member of that struct. What if My functions are not member of a struct? just plain methods in a package. and the calling methods and called methods are in different package. Then?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.