Menu

Tableaux en Golang : longueur fixe, copie par valeur, différence avec les slices

Un tableau Go a une longueur fixe qui fait partie de son type, et il est copié à l'affectation. Apprenez à déclarer, parcourir, comparer et passer des tableaux, et pourquoi la plupart du code Go utilise des slices à la place.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Déclarer un tableau

Un type tableau s'écrit [N]T : une longueur, puis un type d'élément. La longueur est fixée à la compilation et fait partie du type.

Sortie :

[90 0 0 0 75] 5
Tue
[5]int [2 3 5 7 11]
["" "b" "" "d" ""]

Un tableau est toujours entièrement initialisé. Les éléments que vous ne définissez pas contiennent la valeur zéro du type : 0, "", false, nil.

Indices et bornes

Les indices vont de 0 à len(a)-1. Un indice constant hors limites est une erreur de compilation. Un indice variable hors limites provoque un panic à l'exécution.

var a [3]int
a[5] = 1 // compile error: invalid argument: index 5 out of bounds [0:3]

i := 5
a[i] = 1 // panic: runtime error: index out of range [5] with length 3

Parcourir un tableau

for i, v := range a visite chaque élément dans l'ordre. v est une copie de l'élément, donc affecter une valeur à v ne modifie pas le tableau. Écrivez plutôt via l'indice.

Il existe une subtilité propre aux tableaux : range sur une valeur tableau évalue une copie du tableau dès le départ. Si le corps de la boucle modifie des éléments plus loin, v affiche encore les anciennes valeurs. Parcourir &a ou a[:] évite la copie.

Les tableaux sont des valeurs

C'est la principale différence avec les tableaux de C, Java ou JavaScript. Affecter un tableau copie chaque élément. Le passer à une fonction le copie aussi.

Sortie :

[1 2 3] [99 2 3]
[1 2 3]
[0 2 3]

La copie est bon marché pour les petits tableaux et coûteuse pour les gros : passer un [1_000_000]int par valeur copie huit mégaoctets. Passez un pointeur (*[N]T) ou une slice (a[:]) quand le tableau est grand ou que la fonction doit le modifier. Indexer via un pointeur de tableau ne demande pas de * explicite : a[0] fonctionne sur un *[3]int.

Comparer des tableaux et s'en servir comme clés de map

Les tableaux d'éléments comparables acceptent == et !=. Deux tableaux sont égaux quand chaque élément est égal. Cela en fait aussi des clés de map valides, ce que les slices ne sont pas.

Des tableaux de longueurs différentes sont des types différents et ne peuvent pas être comparés du tout : [3]int{} == [4]int{} ne compile pas (mismatched types [3]int and [4]int).

Tableaux multidimensionnels

Un tableau de tableaux vous donne une grille fixe. La grille entière occupe un seul bloc de mémoire contigu.

row[:] transforme la ligne [3]rune en slice []rune, que string() accepte.

Tableau ou slice

Tableau [N]TSlice []T
Longueurfixe, fait partie du typechange avec append
Affectation et passagecopie tous les élémentscopie un petit en-tête, partage les éléments
Valeur zéroN éléments à zéronil, longueur 0
==oui, élément par élémentseulement contre nil
Clé de mapouinon
Usage typiquedonnées de taille fixe : hachages, coordonnées, bufferspresque tout le reste

En pratique, vous croiserez surtout des tableaux à quelques endroits : sha256.Sum256 renvoie un [32]byte, les tables de correspondance dont la taille ne change jamais, et le stockage sous-jacent d'une slice. Découper un tableau avec a[:] ou a[1:3] crée une slice qui partage sa mémoire ; la page sur les slices explique ce que ce partage implique.

Convertir entre tableaux et slices

Convertir une slice en tableau (Go 1.20) ou en pointeur de tableau (Go 1.17) provoque un panic si la slice est plus courte que la longueur du tableau : panic: runtime error: cannot convert slice with length 2 to array or pointer to array with length 3.

Erreurs courantes

  • S'attendre à ce qu'une fonction modifie un tableau passé en argument. Elle en reçoit une copie. Passez *[N]T ou une slice.
  • Utiliser un tableau là où une slice est attendue. []int{1, 2} est une slice, [2]int{1, 2} est un tableau. Une fonction qui prend []int n'acceptera pas un [2]int ; passez a[:].
  • De gros tableaux dans une boucle range. for _, v := range bigArray copie d'abord tout le tableau. Parcourez &bigArray ou une slice.

Questions fréquentes

Comment déclarer un tableau en Go ?

Écrivez la longueur entre crochets avant le type des éléments : var a [5]int crée cinq zéros. Avec des valeurs : a := [3]string{"x", "y", "z"}. Utilisez [...] pour laisser le compilateur compter : a := [...]int{1, 2, 3} a le type [3]int.

Quelle est la différence entre un tableau et une slice en Go ?

Un tableau a une longueur fixe qui fait partie de son type ([3]int et [4]int sont des types différents) et il est copié quand on l'affecte ou le passe. Une slice ([]int) est une vue sur un tableau sous-jacent, dont la longueur peut changer via append, et copier une slice ne copie que la vue, pas les éléments. La plupart du code Go utilise des slices.

Comment obtenir la longueur d'un tableau en Go ?

Utilisez la fonction intégrée len(a). Pour un tableau, c'est une constante connue à la compilation, utilisable dans des expressions constantes. cap(a) renvoie le même nombre.

Peut-on comparer des tableaux en Go ?

Oui, avec == et !=, si le type des éléments est comparable. Deux tableaux sont égaux quand tous leurs éléments sont égaux. Les tableaux peuvent aussi servir de clés de map. Les slices ne se comparent pas avec == (sauf à nil) ; utilisez slices.Equal pour elles.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER