In Go vertegenwoordigt het type struct{} een structuur zonder velden en neemt het 0 bytes geheugen in beslag. Dit is een waardevol kenmerk dat wordt gebruikt om het verbruik van hulpbronnen te minimaliseren in gevallen waar het feit van aanwezigheid belangrijk is, maar geen gegevens nodig zijn — bijvoorbeeld bij de implementatie van verzamelingen (set), signaleringsstructuren of gebeurtenissenkanalen.
Voorbeeld gebruik voor een verzameling:
mySet := make(map[string]struct{}) mySet["foo"] = struct{}{} if _, ok := mySet["foo"]; ok { fmt.Println("foo is aanwezig in mySet") }
struct{} wordt gebruikt als waarde om de aanwezigheid van een sleutel aan te tonen.map[string]bool, is de variant met struct{} zuiniger in geheugen.Signaleringskanalen:
done := make(chan struct{}) // De goroutine wacht op een voltooiingssignaal <-done
Wat is het verschil tussen map[string]struct{} en map[string]bool bij de implementatie van een verzameling? Waarom is map[string]struct{} beter en zijn er nadelen?
Antwoord:
map[string]struct{} gebruikt 0 bytes voor de waarde, de meest compacte optie — het bespaart geheugen, vooral bij een groot aantal gegevens.map[string]bool vereist 1 byte voor de waarde (intern kan dit nog steeds meer geheugen vereisen vanwege uitlijnen).map[string]struct{}: je kunt niet snel een lijst krijgen van alle waarden gemarkeerd als true, als je ooit een logisch resultaat nodig hebt. Het is nog steeds itereren door de sleutels.Voorbeeld:
set := make(map[string]struct{}) set["Alice"] = struct{}{} _, exists := set["Alice"] // true flags := make(map[string]bool) flags["Alice"] = true _, exists := flags["Alice"] // true
Verhaal
In een project voor het opslaan van unieke identificatoren gebruikten ze map[string]bool, wat bij toenemende gegevens leidde tot een aanzienlijke stijging van het geheugengebruik — honderden megabytes in vergelijking met de optie met map[string]struct{}. Overstappen op struct{} verminderde het geheugenverbruik met meer dan de helft.
Verhaal
Een beginner signaleerde de voltooiing van een goroutine via
chan bool. Bij een groot aantal goroutines bleek het verzenden van waarden overbodig: er werd nergens geanalyseerd oftrueoffalsewas ontvangen. Vervangen doorchan struct{}toonde architectonische onnauwkeurigheid aan en vereenvoudigde de code.
Verhaal
In de bibliotheek maakten ze een verzameling via map, waarbij ze string als waarde gebruikten. Dit nam te veel geheugen in beslag. Na een codebeoordeling werd het omgezet naar map[typ]struct{}. De fout werd ontdekt na het analyseren van het geheugengebruik tijdens prestatietests, toen de applicatie crashte door OOM.