In diesem Artikel untersuchen wir ein Problem, das beim Versuch auftritt, Methoden auf einer Schnittstelle dynamisch aufzurufen{} in Go. Unser Ziel ist es, diese Herausforderung zu meistern und einen effizienten Methodenaufruf unabhängig vom zugrunde liegenden Datentyp oder Empfängertyp zu ermöglichen.
Beim Umgang mit der Schnittstelle{} in Go stießen wir auf eine Einschränkung in Dynamischer Methodenaufruf: Wenn die in der Schnittstelle {} gespeicherten Daten ein Zeiger waren, hatten wir Schwierigkeiten, auf seine Adresse zuzugreifen. Folglich konnten Methoden mit Zeigerempfängern nicht dynamisch aufgerufen werden.
Um dieses Problem zu lösen, nutzen wir eine Technik, die vier Fälle umfasst:
Nachdem wir den geeigneten Datentyp ermittelt haben, erstellen wir Führen Sie eine zusätzliche Prüfung auf Existenz der Methode sowohl für den Wert als auch für den Zeiger durch. Dadurch stellen wir den Methodenaufruf sicher, unabhängig davon, ob die Methode als Wert- oder Zeigerempfänger deklariert ist.
Der folgende Code demonstriert die Implementierung unserer Lösung:
package main import ( "fmt" "reflect" ) type Test struct { Start string } // value receiver func (t Test) Finish() string { return t.Start + "finish" } // pointer receiver func (t *Test) Another() string { return t.Start + "another" } func CallMethod(i interface{}, methodName string) interface{} { var ptr reflect.Value var value reflect.Value var finalMethod reflect.Value value = reflect.ValueOf(i) // if we start with a pointer, we need to get value pointed to // if we start with a value, we need to get a pointer to that value if value.Type().Kind() == reflect.Ptr { ptr = value value = ptr.Elem() } else { ptr = reflect.New(reflect.TypeOf(i)) temp := ptr.Elem() temp.Set(value) } // check for method on value method := value.MethodByName(methodName) if method.IsValid() { finalMethod = method } // check for method on pointer method = ptr.MethodByName(methodName) if method.IsValid() { finalMethod = method } if (finalMethod.IsValid()) { return finalMethod.Call([]reflect.Value{})[0].Interface() } // return or panic, method not found of either type return "" } func main() { i := Test{Start: "start"} j := Test{Start: "start2"} fmt.Println(CallMethod(i, "Finish")) fmt.Println(CallMethod(&i, "Finish")) fmt.Println(CallMethod(i, "Another")) fmt.Println(CallMethod(&i, "Another")) fmt.Println(CallMethod(j, "Finish")) fmt.Println(CallMethod(&j, "Finish")) fmt.Println(CallMethod(j, "Another")) fmt.Println(CallMethod(&j, "Another")) }
Durch den Einsatz dieser Technik können wir unabhängig vom Empfängertyp dynamisch Methoden auf der Schnittstelle{} aufrufen und so robusten und anpassungsfähigen Code ermöglichen Los.
Das obige ist der detaillierte Inhalt vonWie rufe ich Methoden auf „interface{}' in Go dynamisch auf, unabhängig vom Empfängertyp?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!