Heim > Backend-Entwicklung > Golang > Wie rufe ich Methoden auf „interface{}' in Go dynamisch auf, unabhängig vom Empfängertyp?

Wie rufe ich Methoden auf „interface{}' in Go dynamisch auf, unabhängig vom Empfängertyp?

DDD
Freigeben: 2024-12-26 20:04:22
Original
604 Leute haben es durchsucht

How to Dynamically Invoke Methods on `interface{}` in Go, Regardless of Receiver Type?

Dynamischer Aufruf von Methoden auf einer Schnittstelle{} Unabhängig vom Empfängertyp

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.

Das Problem

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.

Die Lösung

Um dieses Problem zu lösen, nutzen wir eine Technik, die vier Fälle umfasst:

  1. Schnittstellendaten{} sind ein Wert, Empfänger ist ein Wert: In diesem Fall sind keine Änderungen erforderlich notwendig.
  2. Interface{}-Daten sind ein Zeiger, Empfänger ist ein Wert:Wir erstellen einen neuen Zeiger auf die Interface{}-Daten und rufen den referenzierten Wert ab.
  3. Schnittstelle{} Daten sind ein Wert, Empfänger ist ein Zeiger: Wir erstellen einen neuen Zeiger auf die Schnittstelle{} Daten.
  4. Interface{} Daten sind ein Zeiger, Empfänger ist ein Zeiger:Wir nutzen den vorhandenen Zeiger.

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.

Proof of Concept

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"))
}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage