我MethodByName()在http://golang.org/pkg/reflect/#Value.MethodByName找到了一个函数调用,但它并不是我想要的!(也许是因为我不知道如何使用它...我找不到它的任何例子).我想要的是:
type MyStruct struct {
//some feilds here
}
func (p *MyStruct) MyMethod {
println("My statement.");
}
CallFunc("MyStruct", "MyMethod");
//print out "My statement."
Run Code Online (Sandbox Code Playgroud)
所以我想,首先我需要一些类似的东西StructByName(),之后使用它MethodByName(),是吧!?
小智 53
要在对象上调用方法,请先使用reflect.ValueOf.然后按名称查找方法,最后调用found方法.例如:
package main
import "fmt"
import "reflect"
type T struct {}
func (t *T) Foo() {
fmt.Println("foo")
}
func main() {
var t T
reflect.ValueOf(&t).MethodByName("Foo").Call([]reflect.Value{})
}
Run Code Online (Sandbox Code Playgroud)
sny*_*nyh 19
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")
}
Run Code Online (Sandbox Code Playgroud)
真正的代码需要检查方法的输入数字或方法是否有效.您可以参考此http://gowalker.org/reflect#Type
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{} {
}
Run Code Online (Sandbox Code Playgroud)
所以这没关系
color := Invoke(Circle{}, "GetColor")[0].(Color)
Run Code Online (Sandbox Code Playgroud)
但
Invoke(NotAShape{}, "ForBar")
Run Code Online (Sandbox Code Playgroud)
无法编译因为NotAnShape不是Shape.
如果您无法确定在编译时将使用哪种第一种类型,则可以构建一个映射来存储所有可能的类型,如下所示.
map[string]reflect.Value{
"YourT1" : reflect.ValueOf(YourT1{})
"YourT2" : reflect.ValueOf(YourT2{})
"Circle" : reflect.ValueOf(Cirlce{}) // or reflect.ValueOf(&Circle{})
}
Run Code Online (Sandbox Code Playgroud)