Maison  >  Article  >  développement back-end  >  Les génériques Go 1.18 peuvent-ils gérer les types contravariants dans les signatures de fonction ?

Les génériques Go 1.18 peuvent-ils gérer les types contravariants dans les signatures de fonction ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-17 10:50:02998parcourir

Can Go 1.18 Generics Handle Contravariant Types in Function Signatures?

Génériques avec types contravariants dans Go 1.18 : clarification et limitations

Efforts pour définir une fonction utilisant des génériques dans Go 1.18 qui prend deux fonctions avec des types compatibles, mais non identiques – un comportement contravariant – ont rencontré des défis. Entrons dans les détails pour comprendre pourquoi.

Considérez la définition de fonction suivante :

func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 {
    return func(a A) T2 {
        return right(left(a))
    }
}

Cette fonction vise à diriger la sortie de la fonction de gauche vers la fonction de droite, en enchaînant les calculs. Cependant, lorsque vous essayez de l'utiliser avec l'exemple suivant :

func OpenFile(name string) *os.File {
...
}

func ReadAll(rdr io.Reader) []byte {
...
}

var OpenRead = Pipe(OpenFile, ReadAll)

la compilation échoue. En effet, le compilateur s'attend à ce que T1 soit identique à *os.File, même s'il est compatible avec io.Reader. Bien qu'il puisse sembler raisonnable de s'attendre à ce que les types compatibles soient acceptés, ce n'est pas le cas en raison du manque de prise en charge par Go des types de résultats covariants.

Existe-t-il un moyen de corriger cette signature dans Go 1.18 ?

Malheureusement non. Les génériques de Go n'ont actuellement pas la capacité d'exprimer la convertibilité de type à l'aide de paramètres de type, ce qui rend impossible la modification de la fonction Pipe pour autoriser ce comportement.

Est-ce un bug dans Go 1.18 ?

Non. Comme indiqué dans la FAQ officielle, ce comportement est intentionnel et n'est pas considéré comme un bug.

Solution de contournement

Pour obtenir un résultat similaire, on peut implémenter une étape de conversion manuellement :

func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 {
    return func(a A) T3 {
        return right(any(left(a)).(T2))
    }
}

Cependant, il est important de noter que cette approche n'assure pas la sécurité des types au moment de la compilation.

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