Une tranche de Go contient trois éléments : les données, la longueur et la capacité.
s := make([]int, 0, 10)
La variable s est une tranche d'ints d'une longueur de 0 et d'une capacité de 10. Les fonctions intégrées len() et cap() vous permettent d'obtenir la longueur et la capacité d'une tranche :
len(s) == 0
cap(s) == 10
Pour augmenter la longueur d'une tranche, il suffit de la refaire :
s = s[0:5]
// len(s) == 5
// cap(s) == 10
Pour réduire la longueur, vous pouvez prendre une sous-tranche :
s = s[0:1]
// len(s) == 1
Il existe des moyens plus courts d'invoquer make() :
a := make([]int, 10)
// len(a) == cap(a) == 10
b := make([]int)
// len(b) == cap(b) == 0
C'est très bien, mais que se passe-t-il si vous devez augmenter la longueur d'une tranche au-delà de sa capacité ? Pour ce faire, vous devez allouer une nouvelle tranche et copier le contenu de l'ancienne tranche dans la nouvelle. (La fonction "copy" est une autre fonction intégrée).
t := make([]int, len(s), 20)
copy(t, s)
En Document d'orientation efficace pousse l'exemple un peu plus loin en implémentant une fonction Append qui ajoute une tranche à une autre, en la redimensionnant si nécessaire.
Les tranches sont soutenues par des tableaux ; lorsque vous créez() une tranche d'une capacité spécifique, un tableau de cette capacité est alloué en arrière-plan. La tranche devient alors un "pointeur intelligent" vers ce tableau. Si vous passez cette tranche (ou une sous tranche de cette tranche) à une autre fonction, elle est passée comme un pointeur vers ce même tableau. La création de sous-tranches est donc très bon marché - c'est l'allocation du tableau d'arrière-plan qui est coûteuse.
La bibliothèque standard de Go comprend un certain nombre de paquets de conteneurs - vector, par exemple - qui éliminent la nécessité de gérer manuellement les tranches. Utilisez les slices pour la rapidité, et des classes de conteneurs plus élaborées pour la commodité. (Cela dit, j'utilise toujours les tranches pour la plupart des choses).
Vous vous demandez peut-être pourquoi vous devez vous donner tout ce mal. Après tout, de nombreux langages fournissent des tableaux redimensionnés dynamiquement en tant que primitives. La raison en est liée à la philosophie de Go. Les concepteurs du langage n'ont pas la prétention de savoir quelle est la politique d'allocation appropriée pour votre programme ; au lieu de cela, ils vous donnent les outils dont vous avez besoin pour construire vos propres structures de données.
1 votes
Lecture approfondie : blog.golang.org/go-slices-usage-and-internals