Écrire une fonction générique pour opérer sur plusieurs structures partageant des membres communs peut être difficile, surtout lorsque ces structures appartiennent à un package externe. Cet article explore différentes solutions pour résoudre ce scénario.
Considérez l'obligation d'écrire une fonction qui ajoute des champs spécifiques aux structures de message Firebase, notamment Message et MulticastMessage. Les deux structures contiennent des champs Android et APNS de types identiques, mais elles ne déclarent pas explicitement de relation entre elles.
Au départ, on pourrait tenter de définir une interface générique, firebaseMessage , et implémentez la fonction comme suit :
<code class="go">type firebaseMessage interface { *messaging.Message | *messaging.MulticastMessage } func highPriority[T firebaseMessage](message T) T { message.Android = &messaging.AndroidConfig{...} .... return message }</code>
Cependant, cette approche échoue en raison de l'erreur "message.Android non défini (le type T n'a pas de champ ni de méthode Android)."
Une solution simple consiste à utiliser un commutateur de type pour gérer chaque type de structure spécifique individuellement :
<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>
Cela fonctionne efficacement si le nombre de types dans l'union est limité.
Si l'accès aux membres communs est essentiel, une approche consiste à créer une structure wrapper avec une méthode commune qui peut être appelée par toutes les structures de l'union. L'inconvénient est que plusieurs structures wrapper doivent être créées pour différents types :
<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>
Pour les situations avec de nombreuses structures, la réflexion peut être une solution plus appropriée.
<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>
À noter que cette approche faisant appel à la réflexion, il est essentiel de s'assurer que les champs sont adressables.
En fonction des besoins spécifiques, la solution appropriée peut varier considérablement . Cet article propose plusieurs options viables pour gérer de tels scénarios dans Go.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!