Heim >Backend-Entwicklung >Golang >Liste gängiger Strukturen/Schnittstellen in Golang

Liste gängiger Strukturen/Schnittstellen in Golang

WBOY
WBOYnach vorne
2024-02-13 17:30:11543Durchsuche

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

php-Editor Baicao stellt Ihnen in diesem Artikel die Liste der gängigen Strukturen/Schnittstellen in Golang vor. Golang ist eine Open-Source-Programmiersprache, die leicht zu erlernen, effizient und zuverlässig ist. Sie wird häufig in der Netzwerkprogrammierung, im Cloud Computing und in anderen Bereichen eingesetzt. In Golang sind gemeinsame Strukturen und Schnittstellen sehr wichtige Konzepte, die uns dabei helfen können, die Wiederverwendbarkeit und Skalierbarkeit des Codes zu erreichen. Ich glaube, dass die Leser durch die Einleitung dieses Artikels die allgemeinen Strukturen und Schnittstellen in Golang besser verstehen und anwenden und ihre Programmierkenntnisse verbessern können.

Frageninhalt

Gibt es eine Möglichkeit, eine Liste gängiger Strukturen/Schnittstellen in Go zu erhalten?

Das ist es, was ich erreichen möchte.

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

Das ist der Fehler, den ich bekomme.

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)

Wenn ich das richtig verstehe, ist in go any also ein eigener Typ. Es ist kein Synonym für „welchen Typ auch immer die Laufzeit wünscht“. Meine Frage ist, ist es möglich, so etwas zu tun?

Problemumgehung

Was Sie hier zu tun versuchen, lässt darauf schließen, dass Sie davon ausgehen, dass die Generika von go in der Lage sind, Typen zu löschen (genau wie Java-Generika). aber es ist nicht die Wahrheit.

Sie haben eine List[int],这意味着它的 AddMethode wie diese:

func (l *List) Add(el int) {
    l.Elements = append(l.Elements, el)
}

Versuchen Sie dann, es einem Segment von Objekten hinzuzufügen, die diese Schnittstelle implementieren:

Add(v any)

Nun denken Sie vielleicht, dass int als int 可以用作 any verwendet werden kann, und Sie haben Recht, das ist möglich, aber wenn Sie sehen:

var s []ListInterface[any]

Sie sagen, dass alle Elemente in diesem Slice eine Add-Methode haben, die einen Parameter vom Typ Add 方法,该方法采用 any annimmt. Das bedeutet also:

s[0].Add("foo")
s[1].Add(123)

Sollte immer ein gültiger Anruf sein. Wenn s[0] 的类型为 List[int] (如您的代码片段中的情况),则这不成立。您将尝试将字符串附加到 Elements ,其类型为 []int.

Es gibt ein Sprichwort, dass eine Umkehrung erlaubt sein sollte:

s := []ListInterface[int]{}
s = append(s, &List[any]{})

Es scheint ein List[any] 将接受 int Parameter zu sein, aber das ist auch nicht erlaubt. Dies kann in manchen Fällen nützlich sein, in vielen Fällen kann es jedoch problematisch sein.

Im Wesentlichen werden Generika in Go zur Kompilierzeit verarbeitet. Wenn du List[int] 时,编译器将创建一个类似 List_int 的类型,并在该类型上实现 Add(el int) 方法,与您最终使用的任何其他 List 类型相同。这些类型都不会具有 Add(any) 方法,除非您创建 List[any] erschaffst. Betrachten Sie es als eine vom Compiler unterstützte Generierung von Boilerplate-Code. Keine Laufzeitlöschung.

Ergebnis: List[int]List[any] sind völlig unterschiedliche Typen und können daher nicht nebeneinander in einer Scheibe sitzen, als wären sie vom gleichen Typ. Wenn Sie tun und lassen möchten, was Sie wollen, können Sie Folgendes tun:

func (l *List[T]) AddAny(v any) {
    tv, ok := v.(T)
    if !ok {
        return // or return an error
    }
    l.Add(tv)
}

Verwenden Sie den any-Wert-Ansatz und verwenden Sie eine Typzusicherung, um festzustellen, ob ein bestimmter Wert mit dem zugrunde liegenden Typ der Liste kompatibel ist, und fügen Sie ihn hinzu, wenn dies der Fall ist. Sie können sie dann wie folgt zu einem einzigen Stück hinzufügen:

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

Aber in Wirklichkeit, wenn Sie so etwas tun, schreit der Code nur nach X-Y-Problem, Sie versuchen, Y (Generika) zu verwenden, um Ihr Problem zu lösen, während das eigentliche Problem X ist: Wie lässt sich das Problem am besten lösen?

Das obige ist der detaillierte Inhalt vonListe gängiger Strukturen/Schnittstellen in Golang. 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