Maison > développement back-end > Golang > Liste des structures/interfaces communes à Golang

Liste des structures/interfaces communes à Golang

WBOY
Libérer: 2024-02-13 17:30:11
avant
561 Les gens l'ont consulté

Golang 中的通用结构/接口列表

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.

Contenu de la question

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

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

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 ?

Solution de contournement

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

Essayez ensuite de l'ajouter à une tranche d'objets implémentant cette interface :

Add(v any)
Copier après la connexion

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

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

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

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

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

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!

Étiquettes associées:
source:stackoverflow.com
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