Chiama uno Struct e il suo Metodo per nome in Go?

Ho trovato una funzione chiamata MethodByName() qui http://golang.org/pkg/reflect/#Value.MethodByName ma non è esattamente quello che voglio! (forse perché non so come usarlo … non riesco a trovare alcun esempio con esso). Quello che voglio è:

 type MyStruct struct { //some feilds here } func (p *MyStruct) MyMethod { println("My statement."); } CallFunc("MyStruct", "MyMethod"); //print out My statement." 

Quindi, suppongo, prima ho bisogno di qualcosa come StructByName() e dopo che lo uso per MethodByName() , è giusto ?!

Per chiamare un metodo su un object, utilizzare prima reflect.ValueOf . Quindi trova il metodo in base al nome e infine chiama il metodo trovato. Per esempio:

 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{}) } 
  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") } 

In realtà, è necessario che il codice verifichi validamente il numero di input del metodo o il metodo stesso. È ansible fare riferimento a questo http://gowalker.org/reflect#Type

  1. Controlla “any” è un tipo di struct
  2. Controlla “any” ha il metodo “name”
  3. Controlla il numero del metodo “nome” parametri di input è uguale alla lunghezza di args
  4. Implementare ret da reflect.Value.Interface()

e stai attento al tipo Ptr; oppure Puoi usare SomeInterface{} invece di usare direttamente l’ interface{} per assicurare questo tipo “qualsiasi”, come questo

  type Shape interface { Area() float64 //some method to ensure any is an Shape type. } func Invoke(s Shape, name string, inputs...interface{}) []interface{} { } 

quindi questo è OK

  color := Invoke(Circle{}, "GetColor")[0].(Color) 

ma

  Invoke(NotAnShape{}, "ForBar") 

non può essere compilato perché NotAnShape non è una forma.

Se non sei sicuro di quale sarà il primo tipo utilizzato in fase di compilazione, puoi build una mappa per memorizzare tutti i tipi possibili, come questo.

  map[string]reflect.Value{ "YourT1" : reflect.ValueOf(YourT1{}) "YourT2" : reflect.ValueOf(YourT2{}) "Circle" : reflect.ValueOf(Cirlce{}) // or reflect.ValueOf(&Circle{}) }