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