无论参数类型如何,都可以调用函数。

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

Invoke functions regardless of their parameter types

问题

假设我有一个函数,它位于以下Method结构体的fn属性中:

type Method struct {
  fn interface{}
}

var inst = &Method{func(a, b int) int {
  return a + b
}}

现在,我想调用这个函数并传入两个参数,而不需要显式地将其转换为func(int, int) int,像这样:

a := 5
b := 6
fmt.Println(inst.fn(a, b))

我该如何实现这个目标?是否有一种通用的解决方案?

英文:

Suppose I have a function which resides in the fn property of the following Method struct:

type Method struct {
  fn interface{}
}

var inst = &Method{func(a, b int) int {
  return a + b
}}

Now, I want to invoke this function with two arguments
without explicitly casting it to func(int, int) int like
so

a := 5
b := 6
fmt.Println(inst.fn(a, b))

How can I achieve this? Is there some generic solution for this?

答案1

得分: 3

我知道的唯一方法是使用reflect.Value.Call

type Method struct {
    fn interface{}
}

func (m Method) Call(args ...interface{}) {
    vs := make([]reflect.Value, len(args))
    for i := range args {
        vs[i] = reflect.ValueOf(args[i])
    }
    v := reflect.ValueOf(m.fn)
    v.Call(vs)
}

func main() {
    f := func(a, b int) {
        fmt.Println(a + b)
    }
    m := Method{f}
    m.Call(2, 3)
}

Playground: http://play.golang.org/p/JNtj2EMpu7.

注意:如果fn不是一个函数或者参数的数量或类型不正确,这段代码会引发 panic。如果你不想出现这种情况,你需要自己重新检查所有这些条件。

英文:

The only way I know is by using reflect.Value.Call:

type Method struct {
	fn interface{}
}

func (m Method) Call(args ...interface{}) {
	vs := make([]reflect.Value, len(args))
	for i := range args {
		vs[i] = reflect.ValueOf(args[i])
	}
	v := reflect.ValueOf(m.fn)
	v.Call(vs)
}

func main() {
    f := func(a, b int) {
    	fmt.Println(a + b)
    }
	m := Method{f}
	m.Call(2, 3)
}

Playground: http://play.golang.org/p/JNtj2EMpu7.

Note: this will panic if fn is not a function or if the number or types of arguments are wrong. If you don't want that, you need to recheck all those conditions yourself.

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

发表评论

匿名网友

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

确定