Les tableaux dans le langage de programmation Go

Ce chapitre vous explique les tableaux en GoLang. Vous allez apprendre à initialiser et modifier un tableau et d'accéder à des éléments du tableau dans le langage de programmation GO.

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

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

« 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

ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

31/03/2019 à 13:31
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

31/03/2019 à 09:28
hardy-capucine
Membre Actif
Avatar de hardy-capucine
hardy-capucine
Membre Actif

Est-ce que je peux comparer deux tableaux avec == ?

31/03/2019 à 05:16
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Non, la taille doit être une constante connue à la compilation. Sinon, le compilateur ne peut pas allouer la mémoire nécessaire.

30/03/2019 à 22:01
olivie-noel
Membre Actif
Avatar de olivie-noel
olivie-noel
Membre Actif

Peut-on initialiser un tableau avec une variable comme taille ?

30/03/2019 à 15:05
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Le range est beaucoup plus idiomatique. N'oublie pas d'utiliser _ si tu n'as pas besoin de l'index.

30/03/2019 à 09:42
tlegrand
Membre Actif
Avatar de tlegrand
tlegrand
Membre Actif

Top, le bloc sur le range m'a sauvé la vie, j'utilisais des boucles for classiques partout avant.

30/03/2019 à 05:26
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie que tu as bien déclaré tes dimensions. Si tu fais var tab [1][1]int, alors tab[0][1] est forcément hors limites.

var tab [2][2]int
tab[0][1] = 10 // Ça fonctionne
29/03/2019 à 23:34
alfred44
Membre Actif
Avatar de alfred44
alfred44
Membre Actif

J'ai un souci avec mon tableau à 2 dimensions, je n'arrive pas à modifier la case [0][1].

29/03/2019 à 16:15
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

29/03/2019 à 11:09
alexandria06
Membre Rédacteur
Avatar de alexandria06
alexandria06
Membre Rédacteur

Peut-on mettre des types différents dans le même tableau ?

29/03/2019 à 04:27
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Pas du tout. La taille est connue dès la compilation, donc c'est une opération en temps constant, quasi instantanée.

29/03/2019 à 00:07
robert-charpentier
Membre Actif
Avatar de robert-charpentier
robert-charpentier
Membre Actif

Est-ce que len() est coûteux en performance sur un gros tableau ?

28/03/2019 à 19:20
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

28/03/2019 à 11:37
william-roux
Membre Actif
Avatar de william-roux
william-roux
Membre Actif

J'ai une erreur invalid array index alors que mon index semble bon, je ne comprends pas.

28/03/2019 à 06:07
allard-charlotte
Membre Actif
Avatar de allard-charlotte
allard-charlotte
Membre Actif

Merci pour l'exemple avec replaceByHatim, c'est exactement ce que je cherchais pour manipuler mes données.

28/03/2019 à 01:43
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

27/03/2019 à 19:29
ateixeira
Membre Actif
Avatar de ateixeira
ateixeira
Membre Actif

Est-ce qu'on peut changer la taille d'un tableau statique après l'avoir déclaré ?

27/03/2019 à 15:19
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

27/03/2019 à 09:55
xavier-guillot
Membre Actif
Avatar de xavier-guillot
xavier-guillot
Membre Actif

J'ai testé le slicing avec jours[:], ça marche nickel. Par contre, si je veux copier le tableau, ça fait quoi exactement ?

27/03/2019 à 04:46
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est juste une boucle dans une boucle. Tu utilises range sur le tableau principal, puis un second range sur chaque ligne.

for _, ligne := range doubleTableau {    for _, val := range ligne {        fmt.Println(val)    }}
27/03/2019 à 00:33
guy-lejeune
Membre Actif
Avatar de guy-lejeune
guy-lejeune
Membre Actif

Comment je peux itérer proprement sur un tableau à deux dimensions ? J'ai un peu de mal avec les imbrications.

26/03/2019 à 20:08
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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)-1 pour viser juste à chaque fois.

26/03/2019 à 13:48
william-maury
Membre Actif
Avatar de william-maury
william-maury
Membre Actif

J'essaie d'accéder au dernier élément d'un tableau de 5 cases avec tab[5] et ça crash. Pourquoi ?

26/03/2019 à 06:11
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

25/03/2019 à 23:40

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire