Un tableau a une longueur fixe qui fait partie de son type. Une slice est une vue souple et extensible sur un tableau. Au quotidien en Go, on utilise presque toujours des slices, mais comprendre le tableau en dessous est ce qui fait « déclic ».
Les tableaux : une taille fixe
La longueur d’un tableau est fixée à la déclaration et ne peut pas changer. La
taille fait partie du type : [3]string et [4]string sont donc deux types
différents.
var days [3]string
days[0] = "Lun"
days[1] = "Mar"
days[2] = "Mer"
Comme la longueur est figée, les tableaux sont rigides. C’est pour cela que les slices existent.
Les slices : une vue souple
Un littéral de slice ressemble à un littéral de tableau, sans la taille. Une slice n’a pas de longueur fixe et peut grandir.
primes := []int{2, 3, 5, 7}
len et cap
len renvoie le nombre d’éléments actuellement contenus. cap renvoie combien
elle peut en contenir avant de devoir agrandir son stockage sous-jacent.
s := []int{2, 3, 5, 7}
fmt.Println(len(s), cap(s)) // 4 4
Agrandir une slice avec append
append renvoie une nouvelle slice contenant les éléments ajoutés. Réaffectez
toujours le résultat, en général à la même variable.
s := []int{1, 2}
s = append(s, 3, 4)
// s vaut maintenant [1 2 3 4]
Découper avec a[low:high]
a[low:high] produit une slice de l’indice low jusqu’à high exclu. Chaque
borne peut être omise pour signifier « le début » ou « la fin ».
lettres := []string{"a", "b", "c", "d", "e"}
fmt.Println(lettres[1:3]) // [b c]
fmt.Println(lettres[:2]) // [a b]
fmt.Println(lettres[3:]) // [d e]
Parcourir avec range
for range parcourt une slice en fournissant l’indice et une copie de chaque
élément.
for i, v := range primes {
fmt.Println(i, v)
}
Créer des slices avec make
make construit une slice avec une longueur donnée et, éventuellement, une
capacité. C’est l’outil adapté quand vous savez à peu près combien d’éléments
vous ajouterez.
scores := make([]int, 0, 4) // len 0, cap 4
scores = append(scores, 10) // pas encore de réallocation
Les slices partagent un tableau sous-jacent
C’est le piège classique. Une slice pointe vers un tableau, et les sous-slices partagent ce même tableau. Écrire à travers une vue modifie l’autre.
base := []int{1, 2, 3, 4}
view := base[1:3] // [2 3]
view[0] = 99
fmt.Println(base) // [1 99 3 4]
Un exemple complet
Ce programme construit une slice, y ajoute des éléments, en extrait une
sous-slice et additionne des valeurs collectées avec make. Il compile et
s’exécute tel quel.
package main
import "fmt"
func main() {
// Un littéral de slice.
primes := []int{2, 3, 5, 7}
fmt.Println("primes :", primes, "len :", len(primes), "cap :", cap(primes))
// On l’agrandit avec append.
primes = append(primes, 11, 13)
fmt.Println("après append :", primes)
// Une sous-slice partage le même tableau sous-jacent.
troisPremiers := primes[:3]
fmt.Println("trois premiers :", troisPremiers)
// make crée une slice avec une longueur et une capacité.
scores := make([]int, 0, 4)
for i := 1; i <= 4; i++ {
scores = append(scores, i*i)
}
// On parcourt avec range.
sum := 0
for _, s := range scores {
sum += s
}
fmt.Println("scores :", scores, "somme :", sum)
}
Son exécution affiche :
primes : [2 3 5 7] len : 4 cap : 4
après append : [2 3 5 7 11 13]
trois premiers : [2 3 5]
scores : [1 4 9 16] somme : 30
Erreurs fréquentes
- Ignorer le résultat d’
append.append(s, x)seul perd la nouvelle slice ; vous devez écrires = append(s, x). - Oublier le tableau sous-jacent partagé. Deux slices issues du même tableau voient les écritures l’une de l’autre. Copiez si vous avez besoin d’indépendance.
- Confondre
lenetcap.lenest ce que vous pouvez lire aujourd’hui ;capest la limite du stockage avant une réallocation.
À vous de jouer
Avec numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, construisez une nouvelle
slice ne contenant que les nombres pairs et affichez-la.
Afficher la correction
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evens := make([]int, 0, len(numbers))
for _, n := range numbers {
if n%2 == 0 {
evens = append(evens, n)
}
}
fmt.Println(evens)
}Partir d’une slice vide de capacité len(numbers) évite les réallocations, et la
boucle range ajoute chaque valeur paire, affichant [2 4 6 8 10].
Résumé
- Les tableaux ont une longueur fixe ; les slices sont des vues souples, que l’on utilise le plus souvent.
appendrenvoie une nouvelle slice,len/capla décrivent, etmakela pré-dimensionne.- Les slices partagent un tableau sous-jacent : utilisez
copypour en obtenir une indépendante.
Ensuite, découvrez l’autre collection centrale de Go, les maps clé-valeur, et revenez sur l’itération avec les boucles.