Frage:
Ist es möglich, dynamisch eine Funktion zu erstellen, die eine vordefinierte Schnittstelle implementiert? Gehen Sie mit Reflexion?
Antwort:
In der Originalversion von Go war es nicht möglich, neue Typen mit angehängten Methoden über Reflexion zu erstellen. Mit der Veröffentlichung von Go 1.5 wurden jedoch die Funktionen „reflect.FuncOf“ und „reflect.MakeFunc“ eingeführt, um genau diesen Bedarf zu decken.
Mit diesen Funktionen können Sie einen Funktionstyp definieren und einen Funktionswert erstellen, der diesem entspricht Typ:
funcType := reflect.FuncOf([]reflect.Type{reflect.TypeOf("")}, []reflect.Type{reflect.TypeOf("")}) fn := reflect.MakeFunc(funcType, func(args []reflect.Value) []reflect.Value { ... })
Das erste zu reflektierende Argument.MakeFunc ist der Funktionstyp, während das zweite Argument ein Funktionswert ist, der diesen implementiert Typ.
Im Kontext des gegebenen Beispiels:
type MyService interface { Login(username, password string) (sessionId int, err error) HelloWorld(sessionId int) (hi string, err error) }
Sie könnten eine Funktion erstellen, die diese Schnittstelle mithilfe von Reflektion wie folgt implementiert:
fn := reflect.MakeFunc(reflect.TypeOf((*MyService)(nil)).Elem(), func(args []reflect.Value) []reflect.Value { switch args[0].String() { case "Login": return []reflect.Value{ reflect.ValueOf(1), reflect.ValueOf(nil), } case "HelloWorld": return []reflect.Value{ reflect.ValueOf("Hello, world!"), reflect.ValueOf(nil), } } return []reflect.Value{ reflect.Value{}, reflect.ValueOf(errors.New("Method not found")), } })
Diese Implementierung verwendet eine Switch-Anweisung, um basierend auf dem ersten Argument zu bestimmen, welche Methode der Schnittstelle aufgerufen werden soll. Anschließend werden die entsprechenden Werte für die Ausgabeargumente zurückgegeben.
Das obige ist der detaillierte Inhalt vonKann Go's Reflection Funktionen erstellen, die vordefinierte Schnittstellen implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!