Programmation en Go/Les tableaux

Tableaux

modifier

Un tableau de valeurs est une série consécutive de valeurs, accessibles par leur indice entier, 0, 1, 2 3...taille-1.

En Go, on déclare un tableau en faisant précéder le type des éléments par la taille entre crochets, comme dans [3]int. Par exemple, pour déclarer un tableau de 3 réels :

var tab [4]float32

ou, en déclarant une valeur "littérale" d'un tableau :

var tab = [...]float32{1.0, 2.0, 3.0}

On peut accéder à un élément d'un tableau en faisant suivre le nom de la variable de l'indice dans le tableau, entre crochets :

var un =tab[0]
tab[1] = 5.1

Attention, les indices d'un tableau démarrent à zéro et pas à un.

On ne peut pas accéder à un élément dont l'indice dépasse la taille du tableau, moins un, ou dont l'indice est négatif. On peut obtenir la taille d'un tableau en utilisant la fonction len () :

var taille = len(tab)

Fonction somme

modifier

Voici un exemple de fonction : la somme de 3 réels. Nous allons faire la somme en utilisant un tableau au lieu de passer chaque élément du tableau en paramètre :

func Somme(a [3]float32) (somme float32) {
    for _, v := range a {
        somme += v
    }
    return
}

On déclare ici une fonction nommée Somme qui prend comme paramètre un tableau de 3 réels, et retourne un réel. La valeur de retour, en Go, vient après la liste des paramètres.

for _, v := range a {

Il s'agit d'une boucle d'itération sur chaque élément du tableau "a". Le mot-clé for définit une boucle d'itération, tandis que range définit l'intervalle d'un tableau (ici, "a")

_, v := range a

Deux variables, "_" et "v", prennent comme valeur d'itération l'indice et la valeur, respectivement, de chaque élément du tableau a. Le caractère "_" utilisé comme variable signifie que la valeur de l'indice est ignorée durant l'itération.

return

Ici, nous retournons la valeur "somme" à la fonction qui nous appelle. Ce devrait être écrit "return somme", mais comme nous avions déclaré la valeur de retour avec un nom de variable, la valeur de cette variable est automatiquement retournée. De plus, la variable est initialisée automatiquement (à zéro) ce qui fait encore une opération qui n'est pas écrite.

Les 'tranches'

modifier

Les slices (tranches en français), sont des tableaux au comportement différent. Disons que les tableaux 'classiques' ont une taille fixe tandis que les tranches n'ont pas de taille précise au moment de la compilation.

Les tableaux fixes sont passés par copie lors d'un appel de fonction. Donc, si votre tableau occupe 4 Mégaoctets, tout le contenu du tableau sera copié à chaque appel de fonction ! Ce peut être une source de lenteur dans votre programme, et il y a deux solutions à ce problème :

  1. utiliser un pointeur sur le tableau ou,
  2. utiliser une tranche.

Les tranches sont prévues pour ce cas, de plus elles sont plus pratiques que les tableaux du fait qu'elles ont une taille modifiable.

Le type tranche est défini par le type des éléments précédé par des crochets : "[]int" est une tranche d'entiers.

Pour créer une tranche il suffit de prendre un intervalle d'indices séparés par ":" entre crochets, d'une variable tableau ou d'une autre tranche :

var tranche []int = tab[0:3]
var autre []int = tab[:] // tab est pris en entier dans la tranche autre

Il est aussi possible de déclarer une tranche "littérale" :

var fibonacci = []int{1, 1, 2, 3, 5, 8}

La longueur d'une tranche s'obtient par la fonction len(), comme pour les tableaux. La longueur du tableau sous-jacent est appelée capacité et s'obtient par la fonction cap().

Si l'on ne précise pas le début d'une tranche, c'est le premier élément du tableau comme dans tab[:3], si on ne précise pas la fin comme dans tab[2:], c'est le dernier élément du tableau.

Fonction Somme sur une tranche

modifier

Réécrivons à présent notre fonction Somme avec les tranches :

func Somme (a []int) (somme int) {
    for _,v := range a {
        somme += v
    }
    return
}

Comme on peut le voir, la différence de syntaxe est minime, mais la différence sémantique est réelle.

La fonction append()

modifier

Cette fonction retourne la tranche formée en ajoutant après le dernier élément de la tranche argument, les autres arguments passés à la fonction.

x := []int{1,2,3}
x = append(x, 4, 5, 6)
fmt.Println(x)

Ce code affiche :

[1 2 3 4 5 6]

Allocation

modifier

On peut allouer de la mémoire pour une tranche en utilisant la fonction make(type, longueur, capacité) :

var tranche = make([]int,10,100)