Pourquoi les tableaux
Imaginez que vous avez besoin de déclarer 100 variables de type int, est-ce que vous allez écrire 100 fois cette ligne ?
var var1 int
var var1 int
var var2 int
...
var var100 int
La réponse est NON. Ça sera long et fastidieux, rappelez vous aussi que vous êtes un bon flemmard. Donc impossible pour vous de passer votre temps à déclarer plusieurs variables !
La solution dans ce cas c'est de créer un tableau de type int. Un tableau (array en anglais) est une structure de données qui permet de stocker une collection séquentielle de taille fixe de variables du même type.
Dans ce chapitre nous allons voir que des tableaux statiques, c'est-à-dire des tableaux dont la taille est connue pendant la déclaration, nous verrons les tableaux dynamiques dans un chapitre dédié aux Slice().
Initialisation des tableaux
Voici comment on déclare un tableau statique
var nomTableau [taille] type
Où taille est un nombre entier qui correspond au nombre de variables que le tableau est capable de stocker suivit du type de variable qu'il peut supporter.
Revenons à notre exemple où il fallait déclarer 100 variables de type int, en tableau statique ça donnera quelque chose comme ça :
var tableauInt [100]int
On peut déclarer n'importe quel type de tableau (int, float64 etc ...) et les variables dans votre tableau auront la même valeur par défaut que d'habitude.
Exemple :
package main
import (
"fmt"
)
func main() {
var tableauInt [10]int
var tableauFloat [10]float32
var tableauString [10]string
var tableauBool [10]bool
fmt.Println("Valeur par défaut de la variable tableauInt :", tableauInt)
fmt.Println("Valeur par défaut de la variable tableauFloat :", tableauFloat)
fmt.Println("Valeur par défaut de la variable tableauString :", tableauString)
fmt.Println("Valeur par défaut de la variable tableauBool :", tableauBool)
}
Résultat :
Valeur par défaut de la variable tableauInt : [0 0 0 0 0 0 0 0 0 0]
Valeur par défaut de la variable tableauFloat : [0 0 0 0 0 0 0 0 0 0]
Valeur par défaut de la variable tableauString : [ ]
Valeur par défaut de la variable tableauBool : [false false false false false false false false false false]
Vous pouvez aussi surcharger les valeurs par défaut de votre tableau grâce à des accolades.
package main
import (
"fmt"
)
func main() {
var tableau1 = [5]int{1, 2, 3, 4, 5}
fmt.Println("la taille de mon tableau1 :", len(tableau1))
fmt.Println("les valeurs de mon tableau1 :", tableau1)
}
Information
la fonction len() retourne la taille de votre tableau
Résultat :
la taille de mon tableau1 : 5
les valeurs de mon tableau1 : [1 2 3 4 5]
Accéder aux éléments du tableau
Depuis l'index du tableau
les variables dans votre tableau sont accessibles depuis leur index (numéro de la case).
Attention
Le premier index commence toujours à la case 0 !
Voici un tableau de type string qui stocke les jours de la semaine :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println("jours[0] =", jours[0])
fmt.Println("jours[1] =", jours[1])
fmt.Println("jours[2] =", jours[2])
fmt.Println("jours[3] =", jours[3])
fmt.Println("jours[4] =", jours[4])
fmt.Println("jours[5] =", jours[5])
fmt.Println("jours[6] =", jours[6])
}
Résultat :
jours[0] = lundi
jours[1] = mardi
jours[2] = mercredi
jours[3] = jeudi
jours[4] = vendredi
jours[5] = samedi
jours[6] = dimanche
On peut très vite se tromper en essayant d'accéder à la dernière valeur de notre tableau comme ci-dessous :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println("jours[7] =", jours[7]) // erreur
}
Erreur :
invalid array index 7 (out of bounds for 7-element array)
Sauf que ça ne fonctionne pas car votre compilateur vous explique que vous être hors limites de votre tableau, l'index que vous avez rentré est non valide. Rappelez-vous que le premier index est toujours égal à 0, il faut donc prendre en considération le 0 quand vous calculez la taille de votre tableau, ici la valeur du dernier index est égale à 6 et non à 7.
Voici un moyen plus simple pour récupérer automatiquement la dernière valeur de votre tableau en utilisant la fonction len() :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println("Dernier jour =", jours[len(jours)-1]) // taille du tableau - 1 = dernier index
}
Résultat :
Dernier jour = dimanche
Boucle sur un tableau
Vous pouvez aussi parcourir la totalité de vos variables grâce à la boucle for en utilisant le mot-clé range.
le mot-clé range retourne à la fois l'index et la valeur de l'element itéré du tableau
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
// récupération de l'index et de la valeur
for index, j := range jours {
fmt.Println(j, "est le jour numéro", (index + 1), "de la semaine")
}
}
Résultat :
lundi est le jour numéro 1 de la semaine
mardi est le jour numéro 2 de la semaine
mercredi est le jour numéro 3 de la semaine
jeudi est le jour numéro 4 de la semaine
vendredi est le jour numéro 5 de la semaine
samedi est le jour numéro 6 de la semaine
dimanche est le jour numéro 7 de la semaine
Boucle for len
Il est concevable aussi d'utiliser une boucle for classique en récupérant la taille du tableau avec la fonction len()
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
for i := 0; i < len(jours); i++ {
fmt.Println(jours[i], "est le jour numéro", (i + 1), "de la semaine")
}
}
Résultat :
lundi est le jour numéro 1 de la semaine
mardi est le jour numéro 2 de la semaine
mercredi est le jour numéro 3 de la semaine
jeudi est le jour numéro 4 de la semaine
vendredi est le jour numéro 5 de la semaine
samedi est le jour numéro 6 de la semaine
dimanche est le jour numéro 7 de la semaine
Récupération rapide et condensée
Il est possible comme sur le langage de programmation python de récupérer des valeurs de notre tableau grâce à l'opérateur :. Voici quelques cas d'utilisation :
- Récupérer tous les éléments de notre tableau :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println(jours[:]) // on récupère tous les éléments
}
Résultat :
[lundi mardi mercredi jeudi vendredi samedi dimanche]
- Récupérer les trois premiers éléments de notre tableau :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println(jours[:3]) // trois premiers éléments
}
Résultat :
[lundi mardi mercredi]
- Récupérer tous les résultats à partir du troisième index :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println(jours[3:])
}
Résultat :
[jeudi vendredi samedi dimanche]
- Récupérer les résultats du premier jusqu'au troisième index (exclus) :
package main
import (
"fmt"
)
func main() {
var jours = [7]string{"lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"}
fmt.Println(jours[1:3])
}
Résultat :
[mardi mercredi]
Changer les valeurs des éléments du tableau
Il est permis de modifier la valeur d'une variable dans un tableau en récupérant l'index de l’élément en question
monTableau [indexDeLElement] = nouvelleValeur
Exemple :
package main
import "fmt"
func main() {
var jours = [5]string{"Hatim", "Robert", "Inconnu", "Ahmed", "Inconnu"}
jours[0] = "Alex" // on remplace le premier element (ici Hatim) par Alex
fmt.Println(jours)
jours = replaceByHatim(jours)
fmt.Println(jours)
}
/*
J'utilise une fonction pour vous montrer qu'il est
possible de prendre en paramètre un tableau
mais aussi de retourner un tableau dans une fonction
*/
func replaceByHatim(jours [5]string) [5]string {
for i, jour := range jours {
if jour == "Inconnu" {
jours[i] = "Hatim" // Remplacer "Inconnu" par "Hatim"
}
}
return jours
}
Résultat :
[Alex Robert Inconnu Ahmed Inconnu]
[Alex Robert Hatim Ahmed Hatim]
Tableau à deux dimensions
Initialisation des tableaux à deux dimensions
Un tableau à deux dimensions n'est rien d'autre qu'un tableau qui contient d'autres tableaux (des tableaux dans un tableau).
Un tableau à deux dimensions est composé de :
- lignes : correspond au nombre des sous tableaux inclus dans le tableau principal.
- colonnes: correspond au nombre d'éléments dans les sous tableaux.
Un tableau à deux dimensions peut par exemple être utilisé pour la construction d'une map dans un jeu 2D.
« Map d'un jeu construite depuis un tableau à double dimensions »
Exemple :
package main
import "fmt"
func main() {
const (
maxLigne int = 3 // 3 sous tableaux
maxColonne int = 4 // 4 éléments pour chaque sous tableau
)
var tableau [maxLigne][maxColonne]int // Création d'un tableau à double dimension
fmt.Println(tableau)
}
Résultat :
[[0 0 0 0] [0 0 0 0] [0 0 0 0]]
Modifier les valeurs des tableaux à deux dimensions
Pour modifier la valeur d'un tableau à deux dimensions, il nous faut :
- index de la ligne : permet de récupérer un tableau bien spécifique dans le tableau principal (ex : s'il est égal à 0 alors on récupère le premier tableau du tableau principal).
- index de la colonne : récupérer un élément depuis tableau spécifique.
package main
import "fmt"
func main() {
const (
maxLigne int = 3
maxColonne int = 3
)
var doubleTableau [maxLigne][maxColonne]int
fmt.Println(doubleTableau)
fmt.Println("----------------------")
//modification de la ligne 3, colonne 2
doubleTableau[2][1] = 5 // modification du 2eme élément du 3eme tableau
fmt.Println(doubleTableau)
chaine := "Hello"
fmt.Println(chaine)
}
Résultat :
[[0 0 0] [0 0 0] [0 0 0]]
----------------------
[[0 0 0] [0 0 0] [0 5 0]]
Espace commentaire
Écrire un commentaire
Rejoignez la discussion
Vous devez être connecté pour poster un message.
26 commentaires
D'ailleurs, si vous manipulez des gros tableaux en paramètres de fonctions, passez-les par pointeur pour éviter de copier toute la mémoire sur la stack.
Oui, si les éléments du tableau sont comparables, tu peux comparer deux tableaux de même taille avec
==. Ça vérifie chaque élément un par un.Est-ce que je peux comparer deux tableaux avec
==?Non, la taille doit être une constante connue à la compilation. Sinon, le compilateur ne peut pas allouer la mémoire nécessaire.
Peut-on initialiser un tableau avec une variable comme taille ?
Le
rangeest beaucoup plus idiomatique. N'oublie pas d'utiliser_si tu n'as pas besoin de l'index.Top, le bloc sur le
rangem'a sauvé la vie, j'utilisais des bouclesforclassiques partout avant.Vérifie que tu as bien déclaré tes dimensions. Si tu fais
var tab [1][1]int, alorstab[0][1]est forcément hors limites.J'ai un souci avec mon tableau à 2 dimensions, je n'arrive pas à modifier la case
[0][1].Absolument pas. Un tableau en Go est homogène. Si tu veux mélanger les types, il faut utiliser une interface, mais c'est une autre histoire.
Peut-on mettre des types différents dans le même tableau ?
Pas du tout. La taille est connue dès la compilation, donc c'est une opération en temps constant, quasi instantanée.
Est-ce que
len()est coûteux en performance sur un gros tableau ?Vérifie bien la valeur de ta variable d'index avant l'appel. Affiche-la avec un
fmt.Println(i)juste avant la ligne qui plante.J'ai une erreur
invalid array indexalors que mon index semble bon, je ne comprends pas.Merci pour l'exemple avec
replaceByHatim, c'est exactement ce que je cherchais pour manipuler mes données.Non, c'est impossible. La taille fait partie du type. Si tu as besoin de flexibilité, tu dois utiliser les Slices, qui sont justement là pour ça. Je ferai un article dessus plus tard.
Est-ce qu'on peut changer la taille d'un tableau statique après l'avoir déclaré ?
Attention, en Go, les tableaux sont des types valeur. Si tu fais une assignation
b := a, tu copies tout le contenu du tableau. Ce n'est pas une référence.J'ai testé le slicing avec
jours[:], ça marche nickel. Par contre, si je veux copier le tableau, ça fait quoi exactement ?C'est juste une boucle dans une boucle. Tu utilises
rangesur le tableau principal, puis un secondrangesur chaque ligne.Comment je peux itérer proprement sur un tableau à deux dimensions ? J'ai un peu de mal avec les imbrications.
Parce que tu es hors limites. Comme expliqué dans l'article, on commence à l'index 0.
Pour un tableau de taille 5, tes index vont de 0 à 4. Utilise
len(tab)-1pour viser juste à chaque fois.J'essaie d'accéder au dernier élément d'un tableau de 5 cases avec
tab[5]et ça crash. Pourquoi ?Oui, c'est le comportement standard en Go. Comme précisé dans le chapitre Initialisation des tableaux, les variables sont toujours initialisées avec leur valeur par défaut.
Pour des
int, c'est 0. Si tu veux autre chose, faut surcharger avec les accolades.