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.
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 vous essayez d'attribuer une instance de Y à un élément de type X.
func Fill[X, Y any](slice []X){
for i := range slice {
slice[i] = new(Y) // not work!
}
}
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.
Pour résoudre ce problème, on peut utiliser une opération de conversion explicite dans la fonction :
func Fill[X, Y any](slice []X) {
for i := range slice {
slice[i] = any(*new(Y)).(X)
}
}
Cependant, 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.
Une solution plus robuste et plus sûre implique l'utilisation d'une fonction constructeur :
func Fill[X any](slice []X, f func() X) {
for i := range slice {
slice[i] = f()
}
}
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.
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{} }.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3