Maison  >  Article  >  développement back-end  >  Comment écrire une fonction générique pour gérer les structures avec des membres communs à partir d'un package externe dans Go ?

Comment écrire une fonction générique pour gérer les structures avec des membres communs à partir d'un package externe dans Go ?

Linda Hamilton
Linda Hamiltonoriginal
2024-10-27 09:49:30949parcourir

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

Fonction générique pour gérer différentes structures avec des membres communs à partir d'un package externe

Introduction

É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.

Définition du problème

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.

Tentative et erreur

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 = &amp;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)."

Solution 1 : Type Switch

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é.

Solution 2 : Wrapper avec méthode

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>

Solution 3 : Réflexion

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 := &amp;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.

Conclusion

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn