Maison >développement back-end >Golang >Contravariance peut-il résoudre le problème de compatibilité des types génériques de Go 1.18 dans la fonction Pipe ?

Contravariance peut-il résoudre le problème de compatibilité des types génériques de Go 1.18 dans la fonction Pipe ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-24 07:47:11349parcourir

Can Contravariance Solve Go 1.18's Generic Type Compatibility Issue in the Pipe Function?

Types contravariants dans Go 1.18 Génériques

Dans Go 1.18, les types génériques permettent de définir des fonctions avec des types qui varient en fonction des arguments de type. La contravariance, un type spécifique de variance, permet aux fonctions d'accepter un plus large éventail de types d'entrée tout en conservant une relation bien définie entre les types d'entrée et de sortie.

Fonction Pipe

La fonction Pipe fournie vise à composer des fonctions qui transforment des valeurs. Il s'attend à ce que le type de sortie de la fonction de gauche corresponde au type d'entrée de la fonction de droite. Cependant, dans l'exemple suivant, la compilation échoue :

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))
    }
}

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

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

var OpenRead = Pipe(OpenFile, ReadAll)

Le compilateur se plaint car T1 est considéré comme *os.File même s'il est compatible avec io.Reader.

Y a-t-il une solution ?

Malheureusement, il n'y a aucun moyen dans les génériques Go 1.18 de modifier la signature de Pipe pour activer le comportement souhaité. Go ne prend pas en charge les types de résultats covariants, ce qui signifie que le type de sortie d'une fonction ne peut pas varier en fonction du type d'entrée.

Est-ce un bug ?

Le comportement dans Go 1.18 n'est pas un bug. C'est intentionnel, comme expliqué dans la FAQ pour les génériques Go.

Solution de contournement

Pour résoudre cette limitation, une version modifiée de la fonction Pipe peut être utilisée, mais cela sacrifie la sécurité des types au moment de la compilation :

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))
    }
}

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