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.
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.
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 = &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.
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.
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>
Für Situationen mit zahlreichen Strukturen kann Reflexion eine geeignetere Lösung sein.
<code class="go">func highPriority[T firebaseMessage](message T) T { cfg := &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.
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!