Maison  >  Article  >  développement back-end  >  Paramètres de type plus contraignants dans Golang (en utilisant la méthode Contains pour implémenter une liste générique)

Paramètres de type plus contraignants dans Golang (en utilisant la méthode Contains pour implémenter une liste générique)

WBOY
WBOYavant
2024-02-06 08:15:04487parcourir

Paramètres de type plus contraignants dans Golang (en utilisant la méthode Contains pour implémenter une liste générique)

Contenu de la question

Supposons que je veuille écrire un type list générique qui contient des méthodes utiles telles que :

type list[t any] []t

func (l *list[t]) len() int
func (l *list[t]) get(pos int) (t t, err error)
func (l *list[t]) set(pos int, t t) error
func (l *list[t]) append(t ...t)
func (l *list[t]) insert(t t, pos int) error
func (l *list[t]) remove(pos int) (t t, err error)
// etc...

Cependant, il existe d'autres méthodes utiles qui peuvent nécessiter de restreindre davantage le type d'élément de la listet. Par exemple, nous ne pouvons pas implémenter la méthode contains sur ce t。例如,我们无法在此 list 类型上实现 contains type :

func (l *list[t]) contains(t t) bool {
    for _, s := range *l {
        if s == t { // compiler error: invalid operation: s == t (incomparable types in type set)
            return true
        }
    }
    return false
}

Si nous déclarons list 为,我们只能实现 contains as, nous ne pouvons implémenter que contient

type List[T comparable] []T

Mais cela rend impossible la création de types incomparables list .

Existe-t-il un moyen d'obtenir le meilleur des deux mondes ? C'est-à-dire existe-t-il une méthode tlist[t] ,但在 t 具有可比性的情况下允许它有一个 contains disponible pour les types incomparables ?

J'ai pensé à :

  • Utilisez différents types (par exemple liste incomparable/uncomparablelist/listlist/comparablelist ou
  • /liste comparable)
  • 包含 Créer
  • une fonction au lieu d'une méthode

Mais je n’aime vraiment aucun d’entre eux.

Bonne réponse

go n'a pas de spécialisations, donc je ne pense pas que vous puissiez le faire fonctionner exactement comme ça (pas un expert en génériques cependant).

Je pense qu'un moyen raisonnable de résoudre ce problème est de passer un comparateur explicite :

func (l *list[t]) contains(t t, cmp func(t, t) bool) bool {
    for _, s := range *l {
        if cmp(s, t) {
            return true
        }
    }
    return false
}

Alors vous pouvez

func main() {
    list := list[int]([]int{1,2,3})
    fmt.println(list.contains(2, func(a, b int) bool { return a == b })) // true
}

Pour des types similaires, vous pouvez fournir une valeur par défaut :

func eq[t comparable](a, b t) bool {
    return a == b
}

Donc ce qui précède devient

func main() {
    list := List[int]([]int{1,2,3})
    fmt.Println(list.Contains(2, Eq[int]) // true
}
list 类型中嵌入一个比较器,并为其指定默认值 func(a, b t) bool { return false }Vous pouvez également intégrer un comparateur dans le type

et lui donner une valeur par défaut func(a, b t) bool { return false } et exposer un comparateur personnalisé qui peut lui être transmis Constructeur. Mais cela est peut-être trop obscur pour vous. 🎜

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer