Implementierung von Sets in Golang: Eine praktische Anleitung
Olivia Novak
Dev Intern · Leapcell

Key Takeaways
- Go fehlt ein eingebauter
Set-Typ, aber Maps bieten eine effiziente Alternative. - Die Verwendung von
struct{}als Map-Wert optimiert die Speichernutzung. - Bibliotheken von Drittanbietern wie
golang-setbieten erweiterte Set-Operationen.
In Go gibt es keine eingebaute Set-Datenstruktur, wie sie in einigen anderen Programmiersprachen zu finden ist. Der Map-Typ von Go bietet jedoch eine bequeme Möglichkeit, ein Set zu implementieren, indem er die Einzigartigkeit von Map-Schlüsseln nutzt, um sicherzustellen, dass jedes Element im Set eindeutig ist.
Implementieren eines Sets mit einer Map
Ein gängiger Ansatz zum Erstellen eines Sets in Go ist die Verwendung einer Map mit Schlüsseln, die die Set-Elemente darstellen, und leeren Struct-Werten. Der leere Struct (struct{}) wird bevorzugt, weil er null Byte Speicher belegt, was ihn zu einer effizienten Wahl macht. Hier ist ein Beispiel, wie Sie ein solches Set definieren und verwenden können:
package main import "fmt" // Set stellt eine Sammlung eindeutiger Elemente dar. type Set struct { m map[interface{}]struct{} } // NewSet initialisiert ein neues Set mit den gegebenen Elementen. func NewSet(items ...interface{}) *Set { s := &Set{ m: make(map[interface{}]struct{}), } s.Add(items...) return s } // Add fügt Elemente zum Set hinzu. func (s *Set) Add(items ...interface{}) { for _, item := range items { s.m[item] = struct{}{} } } // Remove löscht ein Element aus dem Set. func (s *Set) Remove(item interface{}) { delete(s.m, item) } // Contains prüft, ob ein Element im Set enthalten ist. func (s *Set) Contains(item interface{}) bool { _, exists := s.m[item] return exists } // Size gibt die Anzahl der Elemente im Set zurück. func (s *Set) Size() int { return len(s.m) } // Clear entfernt alle Elemente aus dem Set. func (s *Set) Clear() { s.m = make(map[interface{}]struct{}) } // Elements gibt einen Slice aller Elemente im Set zurück. func (s *Set) Elements() []interface{} { elements := make([]interface{}, 0, len(s.m)) for key := range s.m { elements = append(elements, key) } return elements } func main() { s := NewSet(1, 2, 3, "four") s.Add(5) s.Remove(2) fmt.Println(s.Contains(3)) // Output: true fmt.Println(s.Size()) // Output: 4 fmt.Println(s.Elements()) // Output: [1 3 four 5] s.Clear() fmt.Println(s.Size()) // Output: 0 }
In dieser Implementierung:
NewSetinitialisiert das Set und fügt alle bereitgestellten Elemente hinzu.Addfügt neue Elemente zum Set hinzu.Removelöscht ein Element aus dem Set.Containsprüft das Vorhandensein eines Elements.Sizegibt die Anzahl der Elemente zurück.Clearentfernt alle Elemente.Elementsruft alle Elemente als Slice ab.
Diese Struktur stellt sicher, dass jedes Element eindeutig ist, und bietet effiziente Operationen zum Hinzufügen, Entfernen und Prüfen von Elementen.
Verwenden von Bibliotheken von Drittanbietern
Für erweiterte Set-Operationen und Funktionen können Sie Bibliotheken von Drittanbietern wie golang-set verwenden. Diese Bibliothek bietet eine Vielzahl von Funktionen, einschließlich Thread-sichere und nicht Thread-sichere Implementierungen, und unterstützt verschiedene Set-Operationen wie Vereinigungen, Schnittmengen und Differenzen.
Um golang-set zu verwenden, installieren Sie es zunächst:
go get github.com/deckarep/golang-set/v2
Hier ist ein Beispiel für die Verwendung:
package main import ( "fmt" mapset "github.com/deckarep/golang-set/v2" ) func main() { s := mapset.NewSet[int]() s.Add(1, 2, 3) s.Remove(2) fmt.Println(s.Contains(3)) // Output: true fmt.Println(s.Cardinality()) // Output: 2 fmt.Println(s.ToSlice()) // Output: [1 3] }
In diesem Beispiel bietet golang-set eine generische Set-Implementierung mit Methoden wie Add, Remove, Contains, Cardinality (um die Anzahl der Elemente zu erhalten) und ToSlice (um alle Elemente als Slice abzurufen).
Leistungsüberlegungen
Bei der Implementierung eines Sets mithilfe einer Map kann die Wahl des Werttyps der Map die Leistung beeinträchtigen. Die Verwendung eines leeren Struct (struct{}) als Werttyp wird oft empfohlen, da er keinen zusätzlichen Speicherplatz verbraucht. Benchmark-Tests haben gezeigt, dass Maps mit struct{}-Werten speichereffizienter sein können als andere Typen wie bool oder int.
Zusammenfassend lässt sich sagen, dass Go zwar keinen eingebauten Set-Typ hat, sein Map-Typ jedoch effiziente und flexible Implementierungen der Set-Funktionalität ermöglicht, entweder durch benutzerdefinierte Implementierungen oder durch die Nutzung von Bibliotheken von Drittanbietern.
FAQs
Die Philosophie von Go bevorzugt Einfachheit, und sein Map-Typ unterstützt effektiv Set-Operationen.
struct{} verbraucht null Byte, wodurch es speichereffizienter ist.
Wenn Sie erweiterte Funktionen wie Vereinigung, Schnittmenge oder Thread-Sicherheit benötigen, ist eine Bibliothek von Vorteil.
Wir sind Leapcell, Ihre erste Wahl für das Hosting von Go-Projekten.
Leapcell ist die Next-Gen Serverless-Plattform für Webhosting, asynchrone Aufgaben und Redis:
Multi-Sprachen-Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 US-Dollar unterstützt 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollautomatische CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und -protokollierung für verwertbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Automatische Skalierung zur mühelosen Bewältigung hoher Parallelität.
- Null Betriebsaufwand – konzentrieren Sie sich einfach auf den Aufbau.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ



