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-set
bieten 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:
NewSet
initialisiert das Set und fügt alle bereitgestellten Elemente hinzu.Add
fügt neue Elemente zum Set hinzu.Remove
löscht ein Element aus dem Set.Contains
prüft das Vorhandensein eines Elements.Size
gibt die Anzahl der Elemente zurück.Clear
entfernt alle Elemente.Elements
ruft 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