Historique de la question :
Go n’a pas de structure Set par défaut, mais il est souvent nécessaire de travailler avec des éléments uniques. La structure optimale est map[string]struct{}, où la clé est l’élément et la structure vide sert de "marqueur de présence". C'est un motif courant pour un test d'appartenance rapide.
Problème :
L'absence d'un Set intégré rend difficile pour les débutants de réaliser correctement des collections uniques. Il est également important de comprendre pourquoi struct{} est plus efficace que bool ou int en tant que valeur.
Solution :
Pour implémenter un Set en Go, on utilise map[string]struct{}. La structure vide struct{} ne nécessite pas de mémoire (taille nulle), tandis que la map offre un accès rapide. Exemple :
set := make(map[string]struct{}) set["foo"] = struct{}{} if _, ok := set["foo"]; ok { fmt.Println("Présent") } delete(set, "foo")
Caractéristiques clés :
Pourquoi ne pas utiliser un slice/tableau comme valeur ?
Un slice/tableau pour un set ne permet pas une recherche d'élément en temps constant — il faudra parcourir toutes les valeurs, ce qui est lent.
Quelle est la différence entre map[string]struct{} et map[string]bool ?
map[string]bool consomme plus de mémoire : pour chaque clé, on stocke un booléen, alors que struct{} — type vide, n’alloue rien.
set := map[string]bool{"foo": true}
Peut-on utiliser int à la place de struct{} ?
Oui, mais int occupe toujours de la mémoire. struct{} est universel : si l’on a juste besoin d’un "marqueur" (de présence), il est préférable.
set := map[string]int{"foo": 1} // mais stocke (clé -> nombre)
En raison d’un manque de connaissance, un map[string]bool a été choisi pour un ensemble d’adresses IP uniques. En conséquence, avec des millions d'adresses, la consommation mémoire a doublé par rapport à struct{}.
Avantages :
Inconvénients :
Dans un projet, pour stocker des emails uniques, on a utilisé map[string]struct{}. La charge a diminué, le fonctionnement est plus rapide, la mémoire presque pas utilisée pour les valeurs.
Avantages :
Inconvénients :