Heim >Backend-Entwicklung >Golang >Wie schreibe ich eine generische Funktion zur Handhabung von Strukturen mit gemeinsamen Mitgliedern aus einem externen Paket in Go?

Wie schreibe ich eine generische Funktion zur Handhabung von Strukturen mit gemeinsamen Mitgliedern aus einem externen Paket in Go?

Linda Hamilton
Linda HamiltonOriginal
2024-10-27 09:49:301111Durchsuche

How to Write a Generic Function for Handling Structs with Common Members from an External Package in Go?

Generische Funktion zur Handhabung verschiedener Strukturen mit gemeinsamen Mitgliedern aus externen Paketen

Einführung

Schreiben einer generischen Funktion zur Bearbeitung mehrerer Strukturen, die gemeinsame Mitglieder haben kann eine Herausforderung sein, insbesondere wenn diese Strukturen zu einem externen Paket gehören. In diesem Artikel werden verschiedene Lösungen zur Bewältigung dieses Szenarios untersucht.

Problemdefinition

Erwägen Sie die Anforderung, eine Funktion zu schreiben, die bestimmte Felder zu Firebase-Nachrichtenstrukturen hinzufügt, einschließlich Message und MulticastMessage. Beide Strukturen enthalten Android- und APNS-Felder identischen Typs, deklarieren jedoch nicht explizit eine Beziehung zueinander.

Versuch und Fehler

Zunächst könnte man versuchen, eine generische Schnittstelle, firebaseMessage, zu definieren , und implementieren Sie die Funktion wie folgt:

<code class="go">type firebaseMessage interface {
    *messaging.Message | *messaging.MulticastMessage
}

func highPriority[T firebaseMessage](message T) T {
    message.Android = &amp;messaging.AndroidConfig{...}
    ....
    return message
}</code>

Dieser Ansatz schlägt jedoch aufgrund des Fehlers „message.Android undefiniert (Typ T hat kein Feld oder Methode Android)“ fehl.

Lösung 1: Typschalter

Eine einfache Lösung besteht darin, einen Typschalter zu verwenden, um jeden spezifischen Strukturtyp einzeln zu behandeln:

<code class="go">func highPriority[T firebaseMessage](message T) T {
    switch m := any(message).(type) {
    case *messaging.Message:
        setConfig(m.Android)
    case *messaging.MulticastMessage:
        setConfig(m.Android)
    }
    return message
}</code>

Dies funktioniert effektiv, wenn die Anzahl der Typen in der Union begrenzt ist.

Lösung 2: Wrapper mit Methode

Wenn der Zugriff auf die gemeinsamen Mitglieder unerlässlich ist, besteht ein Ansatz darin, eine Wrapper-Struktur mit einer gemeinsamen Methode zu erstellen, die von allen Strukturen in der Union aufgerufen werden kann. Der Nachteil besteht darin, dass mehrere Wrapper-Strukturen für verschiedene Typen erstellt werden müssen:

<code class="go">type wrappedMessage interface {
    *MessageWrapper | *MultiCastMessageWrapper
    SetConfig(c foo.Config)
}

type MessageWrapper struct {
    messaging.Message
}

func (w *MessageWrapper) SetConfig(cfg messaging.Android) {
    *w.Android = cfg
}

// same for MulticastMessageWrapper</code>

Lösung 3: Reflexion

Für Situationen mit zahlreichen Strukturen kann Reflexion eine geeignetere Lösung sein.

<code class="go">func highPriority[T firebaseMessage](message T) T {
    cfg := &amp;messaging.Android{} 
    reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
    return message
}</code>

Da bei diesem Ansatz Reflexion zum Einsatz kommt, muss unbedingt sichergestellt werden, dass die Felder adressierbar sind.

Fazit

Abhängig von den spezifischen Anforderungen kann die geeignete Lösung erheblich variieren . Dieser Artikel bietet mehrere praktikable Optionen für den Umgang mit solchen Szenarien in Go.

Das obige ist der detaillierte Inhalt vonWie schreibe ich eine generische Funktion zur Handhabung von Strukturen mit gemeinsamen Mitgliedern aus einem externen Paket in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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