Heim  >  Artikel  >  Backend-Entwicklung  >  Weitere Einschränkung von Typparametern in Golang (mit der Methode „Contains“ zum Implementieren einer generischen Liste)

Weitere Einschränkung von Typparametern in Golang (mit der Methode „Contains“ zum Implementieren einer generischen Liste)

WBOY
WBOYnach vorne
2024-02-06 08:15:04563Durchsuche

Weitere Einschränkung von Typparametern in Golang (mit der Methode „Contains“ zum Implementieren einer generischen Liste)

Frageninhalt

Angenommen, ich möchte einen generischen list-Typ schreiben, der einige nützliche Methoden enthält, wie zum Beispiel:

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...

Es gibt jedoch auch andere nützliche Methoden, die möglicherweise eine weitere Einschränkung des Elementtyps der Listet erfordern. Beispielsweise können wir die Methode contains nicht für diesen t。例如,我们无法在此 list 类型上实现 contains Typ implementieren:

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
}

Wenn wir list 为,我们只能实现 contains als deklarieren, können wir nur contains implementieren

type List[T comparable] []T

Aber das macht es unmöglich, unvergleichliche Typen zu schaffen list .

Gibt es eine Möglichkeit, das Beste aus beiden Welten zu bekommen? D.h. gibt es eine tlist[t] ,但在 t 具有可比性的情况下允许它有一个 contains-Methode für unvergleichliche Typen?

Ich dachte an:

  • Verwenden Sie verschiedene Typen (z. B. uncomparablelist/uncomparablelist/listlist/comparablelist oder
  • /comparablelist)
  • 包含 Machen Sie
  • eine Funktion anstelle einer Methode

Aber ich mag keinen von ihnen wirklich.

Richtige Antwort

go hat keine Spezialisierungen, daher glaube ich nicht, dass Sie es genau so zum Laufen bringen können (allerdings kein Generika-Experte).

Ich denke, ein vernünftiger Weg, dieses Problem zu lösen, besteht darin, einen expliziten Komparator zu übergeben:

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
}

Dann kannst du

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

Für ähnliche Typen können Sie einen Standardwert angeben:

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

So wird das Obige zu

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 }Sie können auch einen Komparator in den Typ

einbetten und ihm einen Standardwert func(a, b t) bool { return false geben und einen benutzerdefinierten Komparator bereitstellen, der an den Konstruktor übergeben werden kann. Aber das könnte für Sie zu unklar sein. 🎜

Das obige ist der detaillierte Inhalt vonWeitere Einschränkung von Typparametern in Golang (mit der Methode „Contains“ zum Implementieren einer generischen Liste). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen