Maison > développement back-end > Golang > Pourquoi la fonction « Pipe » ne parvient-elle pas à se compiler avec les types compatibles dans les génériques Go 1.18 ?

Pourquoi la fonction « Pipe » ne parvient-elle pas à se compiler avec les types compatibles dans les génériques Go 1.18 ?

DDD
Libérer: 2024-11-17 10:30:04
original
506 Les gens l'ont consulté

Why Does the `Pipe` Function Fail to Compile with Compatible Types in Go 1.18 Generics?

Comportement de type contravariant dans Go 1.18 Generics

Go 1.18 a introduit les génériques, qui permettent la création de code de type sécurisé. Cependant, certains comportements peuvent différer des attentes, comme avec les types contravariants.

Considérez la fonction suivante dans Go 1.18 :

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))
    }
}
Copier après la connexion

Cette fonction est conçue pour diriger la sortie de gauche comme entrée à droite. Cependant, il ne parvient pas à se compiler lorsqu'il est utilisé comme suit :

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

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

var OpenRead = Pipe(OpenFile, ReadAll)
Copier après la connexion

Cela est dû au fait que le compilateur détermine que T1 est *os.File, qui n'est pas identique à io.Reader même s'il est compatible.

Le comportement souhaité serait la possibilité de chaîner la fonction Pipe avec des fonctions qui acceptent un type compatible en entrée. Cela correspond au comportement attendu lors de l'appel de la chaîne sans génériques.

Questions :

  1. Existe-t-il un moyen d'ajuster la signature de Pipe pour permettre le comportement souhaité ?
  2. Ce comportement est-il intentionnel ou un bug ?

Réponses :

  1. Non, il n'existe actuellement aucun moyen d'exprimer la compatibilité entre les types à l'aide de génériques dans Go 1.18.
  2. Ce comportement n'est pas un bug. Cela reflète le manque de prise en charge des types de résultats covariants dans Go.

Solution de contournement :

Bien qu'il ne soit pas possible d'obtenir un « type-safe au moment de la compilation ", une solution de contournement possible consiste à utiliser l'assertion de type :

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))
    }
}
Copier après la connexion

Ce code n'est pas de type sécurisé au moment de la compilation, mais il peut fournir la fonctionnalité souhaitée dans certains cas.

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal