Junior
Comment fonctionnent les slices en Go?
sobes.tech IA
Réponse de l'IA
Un slice est une enveloppe légère au-dessus d'un tableau. Il ne stocke pas les données lui-même, mais fait référence à un tableau de base.
Structure du slice :
- Pointeur vers le tableau de base : Adresse du premier élément du slice en mémoire.
- Longueur (Length) : Nombre d'éléments dans le slice.
- Capacité (Capacity) : Nombre d'éléments dans le tableau de base, disponibles à partir du pointeur du slice.
// Exemple de déclaration d'un slice
var s []int
s = append(s, 1, 2, 3) // Ajout d'éléments
// Représentation interne du slice s (simplifiée)
// struct SliceHeader {
// Data uintptr // Pointeur vers le tableau de base
// Len int // Longueur du slice
// Cap int // Capacité du slice
// }
- Lors de la création d'un slice avec
make([]T, length, capacity), un tableau de base avec la capacité spécifiée est créé, et un slice qui y fait référence avec la longueur indiquée. - Lorsqu'on utilise une tranche sur un tableau ou un autre slice (par exemple,
arr[low:high:max]), un nouveau slice est créé, qui fait référence à la même zone mémoire du tableau de base, mais avec des pointeurs, une longueur et une capacité différentes. - L'opération
appendpeut entraîner une réallocation de mémoire. Si la capacité actuelle n'est pas suffisante pour ajouter de nouveaux éléments, Go crée un nouveau tableau de base plus grand, copie les éléments de l'ancien et met à jour le pointeur du slice vers le nouveau tableau. Cela s'appelle une relocalisation. La croissance de la capacité lors de l'append est exponentielle (double jusqu'à une certaine taille, puis ralentit). - Les slices sont passés par valeur, mais comme ils contiennent un pointeur vers le tableau de base, les modifications des éléments du slice (via l'index) seront visibles dans tous les slices faisant référence au même tableau.
- Modifier la longueur du slice via une tranche n'affecte pas le tableau de base, mais peut limiter l'accès à une partie des données du tableau de base.
Tableau : Comparaison entre Longueur et Capacité
| Caractéristique | Longueur (Length) | Capacité (Capacity) |
|---|---|---|
| Définition | Nombre réel d'éléments dans le slice | Nombre maximum d'éléments que le slice peut contenir sans relocalisation |
| Accès | Utilisé pour accéder aux éléments (s[i]) | Détermine combien d'éléments supplémentaires peuvent être ajoutés avec append avant la relocalisation |
| Obtention | len(s) |
cap(s) |
// Exemple de travail avec la capacité et la longueur
s := make([]int, 0, 5) // Longueur 0, capacité 5
fmt.Println(len(s), cap(s)) // 0 5
s = append(s, 1, 2) // Ajout de 2 éléments
fmt.Println(len(s), cap(s)) // 2 5
s = append(s, 3, 4, 5, 6) // Ajout de 4 autres éléments, nécessite une relocalisation
fmt.Println(len(s), cap(s)) // 6 10 (la capacité a augmenté)