
Les collections sont le pain quotidien de tout programme Go : listes de résultats, tables de correspondance, ensembles de valeurs. Ce guide vous apprend à manipuler les trois structures de base, les tableaux, les slices et les maps, et surtout à éviter le piège qui surprend tous les débutants : en Go, un slice partage sa mémoire, et modifier une vue peut modifier l'original. Public visé : vous connaissez déjà les variables et fonctions Go. Tous les exemples sont testés sur Go 1.26.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Distinguer un tableau à taille fixe d'un slice dynamique.
- Faire croître un slice avec
appendet comprendrelen/cap. - Éviter le piège du partage de mémoire grâce à
copy. - Associer des clés à des valeurs avec une map.
Tableau à taille fixe ou slice dynamique ?
Section intitulée « Tableau à taille fixe ou slice dynamique ? »Go propose deux structures pour une suite de valeurs. Le tableau (array) a une taille fixe, connue à la compilation. Le slice est une vue dynamique qui peut grandir : c'est celui qu'on utilise 95% du temps.
var tab [3]int = [3]int{1, 2, 3} // tableau : 3 cases, ni plus ni moinssli := []int{1, 2, 3} // slice : pas de taille entre les crochetssli = append(sli, 4) // on ajoute un élémentfmt.Println(tab, sli) // [1 2 3] [1 2 3 4]La différence tient dans les crochets : [3]int fixe la taille, []int la laisse libre. Un tableau sert quand la taille est immuable et connue (une matrice, une couleur RVBA) ; partout ailleurs, on prend un slice.
make, len et cap : comment un slice grandit
Section intitulée « make, len et cap : comment un slice grandit »Un slice a deux mesures : sa longueur (len, le nombre d'éléments) et sa capacité (cap, la place réservée en mémoire avant de devoir réallouer). La fonction make permet de pré-réserver cette capacité.
s := make([]int, 0, 2) // longueur 0, capacité 2fmt.Printf("len=%d cap=%d\n", len(s), cap(s))for i := 1; i <= 3; i++ { s = append(s, i) fmt.Printf("après append(%d): len=%d cap=%d\n", i, len(s), cap(s))}Sortie :
len=0 cap=2après append(1): len=1 cap=2après append(2): len=2 cap=2après append(3): len=3 cap=4Tant que la capacité suffit, append remplit les cases réservées. Au troisième ajout, la capacité de 2 est dépassée : Go réalloue un nouveau tableau plus grand (ici la capacité double à 4) et recopie les éléments. Pré-réserver avec make([]int, 0, N) quand on connaît la taille finale évite ces réallocations et accélère le code.
Le piège du partage de mémoire
Section intitulée « Le piège du partage de mémoire »Voici l'erreur qui piège tout le monde. Un slice n'est pas les données : c'est une fenêtre sur un tableau en mémoire. Découper un slice avec base[1:3] crée une autre fenêtre sur le même tableau. Modifier l'une modifie l'autre.
base := []int{10, 20, 30, 40}vue := base[1:3] // vue partage la mémoire de basevue[0] = 99fmt.Println(base) // [10 99 30 40] : base a changé !On voulait ne toucher que vue, mais base est modifiée. Pour obtenir une copie indépendante, on alloue un nouveau slice et on utilise copy :
base2 := []int{10, 20, 30, 40}indep := make([]int, 2)copy(indep, base2[1:3])indep[0] = 99fmt.Println(base2, indep) // [10 20 30 40] [99 30] : base2 intacteRetenez la règle : un sous-slice partage la mémoire de son parent. Dès que vous devez modifier une portion sans toucher l'original, passez par copy.
Les maps : associer des clés à des valeurs
Section intitulée « Les maps : associer des clés à des valeurs »La map est la structure clé-valeur de Go, idéale pour indexer des données par un identifiant. On la crée avec un littéral ou make, et on accède aux valeurs par leur clé.
stock := map[string]int{"pommes": 5, "poires": 3}stock["bananes"] = 7 // ajout ou mise à jour
if n, ok := stock["pommes"]; ok { // le second retour ok dit si la clé existe fmt.Println("pommes en stock:", n)}delete(stock, "poires") // suppressionLe motif valeur, ok := map[clé] est essentiel : ok vaut false si la clé est absente, ce qui évite de confondre « clé absente » et « valeur zéro ». Un accès à une clé inexistante ne plante pas, il renvoie la valeur zéro du type (0 pour un int).
L'itération sur une map se fait avec range, mais l'ordre n'est pas garanti et change à chaque exécution. Pour un affichage stable, on trie les clés :
cles := make([]string, 0, len(stock))for k := range stock { cles = append(cles, k)}sort.Strings(cles) // ordre déterministefor _, k := range cles { fmt.Printf("%s: %d\n", k, stock[k])}Exercice : compter les occurrences de mots
Section intitulée « Exercice : compter les occurrences de mots »Cet exercice combine slice et map. Essayez de le résoudre avant d'ouvrir la solution.
Écrivez un programme qui compte combien de fois chaque mot apparaît dans une phrase.
- Partez d'un slice de mots :
[]string{"go", "est", "simple", "go", "est", "rapide", "go"}. - Construisez une map
map[string]intqui associe chaque mot à son nombre d'occurrences. - Affichez combien de fois le mot
"go"apparaît.
Indice : sur une map, compte[mot]++ fonctionne même si la clé n'existe pas encore (elle démarre à la valeur zéro 0).
L'astuce tient dans l'incrémentation directe : compte[mot]++ lit la valeur actuelle (0 si absente) et l'incrémente.
package main
import "fmt"
func main() { phrase := []string{"go", "est", "simple", "go", "est", "rapide", "go"} compte := map[string]int{}
for _, mot := range phrase { compte[mot]++ // 0 par défaut, puis +1 }
fmt.Println("go apparaît", compte["go"], "fois")}Résultat :
go apparaît 3 foisPas besoin de vérifier si la clé existe avant d'incrémenter : la valeur zéro d'un int est 0, donc le premier ++ la fait passer à 1. C'est un idiome Go très courant pour compter ou regrouper.
À retenir
Section intitulée « À retenir »- Le tableau (
[3]int) a une taille fixe ; le slice ([]int) est dynamique et sert dans la quasi-totalité des cas. - Un slice a une longueur (
len) et une capacité (cap) ;appendréalloue quand la capacité est dépassée. - Piège majeur : un sous-slice
base[1:3]partage la mémoire du parent ; utilisezcopypour une copie indépendante. - La map associe des clés à des valeurs ; le motif
v, ok := m[k]teste la présence d'une clé. - L'ordre d'itération d'une map n'est pas garanti : triez les clés pour un affichage stable.