l'éditeur php Baicao vous présentera la liste des structures/interfaces communes dans Golang dans cet article. Golang est un langage de programmation open source facile à apprendre, efficace et fiable. Il est largement utilisé dans la programmation réseau, le cloud computing et d'autres domaines. Dans Golang, les structures et interfaces communes sont des concepts très importants qui peuvent nous aider à atteindre la réutilisabilité et l'évolutivité du code. Grâce à l'introduction de cet article, je pense que les lecteurs peuvent mieux comprendre et appliquer les structures et interfaces communes de Golang et améliorer leurs compétences en programmation.
Existe-t-il un moyen d'obtenir une liste des structures/interfaces communes ?
C'est ce que je veux réaliser.
<code>package main type List[T any] struct { Elements []T } func (f *List[T]) Add(el T) { f.Elements = append(f.Elements, el) } type ListInterface[T any] interface { Add(el T) } func main() { listOfLists := make([]ListInterface[any], 0) listOfLists = append(listOfLists, &List[int]{}) } </code>
C'est l'erreur que j'obtiens.
cannot use &List[int]{} (value of type *List[int]) as ListInterface[any] value in argument to append: *List[int] does not implement ListInterface[any] (wrong type for method Add) have Add(int) want Add(any)
Donc, si je comprends bien, le go any
est son propre type. Ce n'est pas un synonyme de "quel que soit le type souhaité par le runtime". Ma question est la suivante : est-il possible de faire quelque chose comme ça ?
Ce que vous essayez de faire ici suggère que vous vous attendez à ce que les génériques de go soient capables d'effacer le type (tout comme les génériques Java). mais ce n'est pas la vérité.
Vous avez une List[int]
,这意味着它的 Add
méthode comme celle-ci :
func (l *List) Add(el int) { l.Elements = append(l.Elements, el) }
Essayez ensuite de l'ajouter à une tranche d'objets implémentant cette interface :
Add(v any)
Maintenant, vous pourriez penser que int
peut être utilisé comme int
可以用作 any
, et vous avez raison, c'est possible, mais quand vous voyez :
var s []ListInterface[any]
Vous dites que tous les éléments de ladite tranche auront une méthode Add
qui prend un paramètre de type Add
方法,该方法采用 any
donc cela signifie :
s[0].Add("foo") s[1].Add(123)
Devrait toujours être un appel valide. Si s[0]
的类型为 List[int]
(如您的代码片段中的情况),则这不成立。您将尝试将字符串附加到 Elements
,其类型为 []int
.
Il y a un dicton selon lequel l'inversion devrait être autorisée :
s := []ListInterface[int]{} s = append(s, &List[any]{})
Il semble List[any]
将接受 int
paramètre, mais ce n'est pas non plus autorisé. Cela peut être utile dans certains cas, mais dans de nombreux cas, cela peut poser problème.
Essentiellement, les génériques dans Go sont quelque chose qui est géré au moment de la compilation. Quand vous créez List[int]
时,编译器将创建一个类似 List_int
的类型,并在该类型上实现 Add(el int)
方法,与您最终使用的任何其他 List
类型相同。这些类型都不会具有 Add(any)
方法,除非您创建 List[any]
. Considérez-le comme une génération de code passe-partout assistée par le compilateur. Pas d'effacement de type d'exécution.
Résultat : List[int]
和 List[any]
sont de types complètement différents et ne peuvent donc pas s'asseoir côte à côte dans une tranche comme s'ils étaient du même type. Si vous voulez pouvoir faire ce que vous voulez, vous pouvez faire ceci :
func (l *List[T]) AddAny(v any) { tv, ok := v.(T) if !ok { return // or return an error } l.Add(tv) }
Adoptez l'approche any
value, en utilisant une assertion de type pour voir si une valeur donnée est compatible avec le type sous-jacent de la liste, et ajoutez-la si tel est le cas. Vous pouvez ensuite les ajouter en une seule tranche comme ceci :
type Lists interface { AddAny(any) } s := []Lists{} s = append(s, &List[int]{}, &List[string]{}) s[0].AddAny(123) // will work s[0].AddAny("foo") // will not, with the current code this will silently fail s[1].AddAny("foo") // works fine s[1].AddAny(123) // silently fails
Mais en réalité, lorsque vous faites quelque chose comme ça, le code crie juste un problème X-Y, vous essayez d'utiliser Y (génériques) pour résoudre votre problème, alors que le vrai problème est X : quelle est la meilleure façon de résoudre le problème ?
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!