英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论