Maison  >  Article  >  développement back-end  >  ## Comment initialiser des tranches d'interfaces avec des types concrets dans Go ?

## Comment initialiser des tranches d'interfaces avec des types concrets dans Go ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-25 14:01:02954parcourir

## How to Initialize Slices of Interfaces with Concrete Types in Go?

Initialisation générique avec des interfaces et des types concrets dans Go

Lors de l'écriture de fonctions génériques dans Go, il peut être avantageux d'accepter également des types concrets. Cependant, cela pose un défi lorsque l'on tente d'initialiser des tranches d'interfaces avec de nouvelles instances de ces types spécifiques.

Tentatives initiales avec plusieurs paramètres de type

Une approche peut sembler logique : définir deux paramètres de type, un pour le type d'élément slice (X) et un pour le type concret (Y) à instancier. Cependant, cette approche échoue lorsque l'on tente d'attribuer une instance de Y à un élément de type X.

<code class="go">func Fill[X, Y any](slice []X){
   for i := range slice {
      slice[i] = new(Y) // not work!
   }
}</code>

Ce problème survient car le compilateur perd la relation entre l'interface X et son implémentation Y. X et Y sont traités comme des types distincts.

Utilisation du casting explicite

Pour résoudre ce problème, on peut utiliser une opération de casting explicite dans la fonction :

<code class="go">func Fill[X, Y any](slice []X) {
    for i := range slice {
        slice[i] = any(*new(Y)).(X)
    }
}</code>

Cependant, cela Cette approche déclenche une panique si Y n'implémente pas X, ce qui se produit dans des scénarios tels que la tentative d'attribuer un *sync.Mutex (type de pointeur) à sync.Locker.

Utilisation d'une fonction constructeur

Une solution plus robuste et plus sécurisée consiste à utiliser une fonction constructeur :

<code class="go">func Fill[X any](slice []X, f func() X) {
    for i := range slice {
        slice[i] = f()
    }
}</code>

Cette fonction accepte une fonction constructeur qui renvoie une nouvelle instance du type spécifié. Cela permet une initialisation concise et sûre des tranches avec des instances de type concret.

Éviter les valeurs nulles

Dans les cas où le type concret est destiné à être instancié avec un type pointeur, il est important de noter ce new(Y) donnera une valeur nulle. Pour contourner cela, on peut ajuster la fonction constructeur pour renvoyer la valeur correcte du pointeur, comme func() X { return &sync.Mutex{} }.

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