Maison >développement back-end >Golang >Comment prendre en charge plusieurs versions de la même interface ?

Comment prendre en charge plusieurs versions de la même interface ?

WBOY
WBOYavant
2024-02-06 09:09:151170parcourir

Comment prendre en charge plusieurs versions de la même interface ?

Contenu de la question

J'écris un module go qui implémente une structure qui satisfait une interface. Nous souhaitons uniquement conserver une seule version de la bibliothèque, mais nos clients utilisent plusieurs versions de l'une de nos dépendances.

Les dépendances fournissent l'interface que nous souhaitons implémenter comme indiqué ci-dessous.

type supercoolinterface interface {
    dooldcoolthing(value string)
}

Notre mise en œuvre est comme ça.

type supercoolimpl struct {}

func (sc *supercoolimpl) dooldcoolthing(value string) {}

La nouvelle version des dépendances ajoute de nouveaux types dans le module types.

type newtype struct {
  value string
}

La dépendance ajoute une méthode à l'interface.

type supercoolinterface interface {
    dooldcoolthing(value string)
    donewcoolthing(value types.newtype)
}

Maintenant, si j'implémente la nouvelle méthode, elle ne sera pas compilée avec l'ancienne version de la bibliothèque car types.newtype n'existe pas. Cependant, je ne peux pas satisfaire à la nouvelle version de l'interface si je n'implémente pas la nouvelle version.

type SuperCoolImpl struct {}

func (sc *SuperCoolImpl) DoOldCoolThing(value string) {}
func (sc *SuperCoolImpl) DoNewCoolThing(value types.NewType) {}

Devons-nous forker le code pour prendre en charge cette version ? Dans les langages avec préprocesseurs, il existe une solution simple, donc je suppose que go doit avoir une solution qui me manque.

Nous prévoyons de continuer à développer et à prendre en charge les deux versions, donc devoir assurer la cohérence entre deux versions différentes peut être ennuyeux. J'espère pouvoir faire quelque chose avec réflexion ou quelque chose de similaire au préprocesseur c où je peux définir une valeur de préprocesseur et implémenter la méthode uniquement si nous demandons à la version de la bibliothèque d'avoir le type correct.


Bonne réponse


J'ai trouvé une solution qui convient à ma situation.

Merci à @Burak Serdar de m'avoir orienté dans la bonne direction.

Ma solution consistait à mettre l'ancienne implémentation dans le package impl/v0 et la nouvelle implémentation dans le package impl/v1.

Les clients utilisant des versions plus anciennes de dépendances utiliseront impl/v0, et les clients utilisant des versions plus récentes de dépendances utiliseront impl/v1.

Étant donné que Golang ne compile que le code directement importé, seuls les packages avec la version d'interface correcte seront compilés, donc les deux sens seront compilés avec succès.

Cela atténue mes craintes de devoir bifurquer toute la bibliothèque.

EDIT : Si quelqu'un utilise cette solution, il y a un problème si vous utilisez actuellement go test ./... pour exécuter vos tests. La commande semble essayer de construire chaque module, qu'il contienne des tests ou non.

Mais vous pouvez utiliser go test $(go list ./... | grep -v <path_to_ignore>)</path_to_ignore> pour exclure des tests, que vous pouvez ensuite exécuter sur la version correcte dans une autre commande.

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer