type YourT1 struct {}
func (y YourT1) MethodBar() {
//do something
}
type YourT2 struct {}
func (y YourT2) MethodFoo(i int, oo string) {
//do something
}
func Invoke(any interface{}, name string, args... interface{}) {
inputs := make([]reflect.Value, len(args))
for i, _ := range args {
inputs[i] = reflect.ValueOf(args[i])
}
reflect.ValueOf(any).MethodByName(name).Call(inputs)
}
func main() {
Invoke(YourT2{}, "MethodFoo", 10, "abc")
Invoke(YourT1{}, "MethodBar")
}
确实代码需要检查方法的输入号,甚至方法本身是否存在。
你可以参考这个http://gowalker.org/reflect#Type
- 检查“any”是一个结构类型
- 检查“any”有“name”方法
- 检查方法“名称”输入参数的数量是否等于 args 的长度
- 实施者
ret
_reflect.Value.Interface()
并注意 Ptr 类型;
或者您可以使用SomeInterface{}
而不是直接使用interface{}
来确保这种“任何”类型,如下所示:
type Shape interface {
Area() float64 //some method to ensure any is an Shape type.
}
func Invoke(s Shape, name string, inputs...interface{}) []interface{} {
}
所以这没关系
color := Invoke(Circle{}, "GetColor")[0].(Color)
但
Invoke(NotAShape{}, "ForBar")
无法编译,因为NotAnShape
它不是 Shape。
如果您在编译时不能确定第一种类型,您可以构建一个映射来存储所有可能的类型,如下所示:
map[string]reflect.Value{
"YourT1" : reflect.ValueOf(YourT1{})
"YourT2" : reflect.ValueOf(YourT2{})
"Circle" : reflect.ValueOf(Cirlce{}) // or reflect.ValueOf(&Circle{})
}