如何在Go中通过字符串方法名调用另一个包的方法

huangapple go评论93阅读模式
英文:

How To Call Method of another package from string method name in Go

问题

假设我有两个包,如下所示:

  • a
  • b

包a中有一些方法,例如:

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

我需要通过方法名的字符串来调用包a中的方法,比如我得到字符串"TestOne",然后调用TestOne()方法。如何实现这个目标呢?

编辑:
我已经了解了reflect。但是reflect需要一个结构体,并且函数必须是该结构体的成员。如果我的函数不是结构体的成员,而只是包中的普通方法,并且调用方法和被调用方法位于不同的包中,那么该怎么办呢?

注意:有些方法可能还带有参数。

英文:

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.

答案1

得分: 6

根据LightWeight在他的回答中所说,你可以使用反射。

你可以使用reflect.ValueOf方法来获取类型的值。然后,你可以使用MethodByName方法来获取函数值。一旦你有了函数值,你可以调用Call方法来执行它。

代码示例

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)
	}
	//返回值
	_ = out
	out, err = CallFuncByName(t1, "FuncTwo", "monkey")
	if err != nil {
		panic(err)
	}
	//返回值
	_ = out
}
英文:

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
}

答案2

得分: 0

你可以尝试在Go语言中使用反射(reflect)。这个链接可能对你有所帮助:https://golang.org/pkg/reflect/ 和 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}
英文:

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}

huangapple
  • 本文由 发表于 2015年10月8日 12:26:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/33006628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定