Discussion du code bases1

Concepts

Les concepts abordés dans cet exemple sont:

  1. Les variables mutables ou non, les constantes.
  2. Les structures de contrôle if ... else et for.
  3. L'utilisation de tableaux statiques.
  4. L'utilisation de macros pour la gestion d'erreurs ou les sorties dans le terminal.

Discussion

Chaque code Rust a un unique point d'entrée: la fonction fn main() {}. Ainsi, le code le plus simple (qui ne fait absolument rien) est.

fn main() {
}

Le corps de votre programme se trouvera donc entre les accolades.

Variables, variables mutables, et constantes

Dans l'ordre d'apparition, nous avons d'abord une constante nommée SIZE, dont le type est usize (entier non signé dont la taille dépend de l'architecture, 8 octets sur une architecture 64 bits) et qui vaut 9. Le nom du type vient après :.

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
}

Ensuite nous déclarons un tableau statique (alloué sur la pile) d'entiers 32 bits et de taille SIZE.

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
let tab: [i32; SIZE] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
}

Vous notez le mot clé let qui permet de déclarer une variable immutables (les valeurs contenues dans tab ou sa taille ne pourront plus changer). On dit qu'on lie (ou bind en anglais) tab à la valeur du [10, 32, 12, 43, 52, 53, 83, 2, 9]. Plus bas nous déclarons au contraire une variable mutable (qui elle pourra changer de valeur au cours de l'exécution du programme).

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
let tab: [i32; SIZE] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
let mut min = tab[0];
}

et l'initialisons avec la valeur du 1er élément de tab (ici la valeur est 10).

Structures de contrôle

Voici deux extraits de code. Dans le premier

#![allow(unused)]
fn main() {
const SIZE: usize = 0;
if SIZE == 0 {
    panic!("Size is of tab = 0.");
}
}

nous testons si SIZE == 0 et utilisons la macro panic! qui lorsqu'elle est exécutée fait quitter le programme et affiche le message d'erreur en argument. Ainsi le code ci-dessus retourne:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.56s
     Running `target/debug/playground`
thread 'main' panicked at 'Size is of tab = 0.', src/main.rs:5:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Dans le second cas, nous sommes dans une boucle for

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
let tab: [i32; SIZE] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
let mut min = tab[0];
for i in 1..SIZE {
    if min > tab[i] {
        min = tab[i];
    }
}
}

où l'indice i prend successivement les valeur 1 à SIZE-1 (la notation a..b veut dire de a à b non inclus) et assignons la valeur tab[i] à la variable mutable min. Si nous avions omis le mot clé mut lors de la déclaration de min l'assignation donnerait une erreur (cliquez sur "play" pour la démonstration)

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
let tab: [i32; SIZE] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
let min = tab[0];
for i in 1..SIZE {
    if min > tab[i] {
        min = tab[i];
    }
}
}

Macros

Outre la macro panic!() nous utilisons ici deux macros permettant d'afficher des chaînes de caractère dans le terminal. Les macros sont toujours identifiées à l'aide du ! se trouvant à la fin de l'appel, comme pour panic!(), print!() (affiche la chaîne de caractère en argument) ou println!() (qui est comme print!() mais retourne à la ligne après avoir affiché). Comme on le voit dans les lignes suivantes

#![allow(unused)]
fn main() {
const SIZE: usize = 9;
let tab: [i32; SIZE] = [10, 32, 12, 43, 52, 53, 83, 2, 9];
let mut min = tab[0];
for i in 1..SIZE {
    if min > tab[i] {
        min = tab[i];
    }
}
println!("Among the numbers in the list:");
for i in 0..SIZE {
    print!("{} ", tab[i]);
}
println!();
}

le formatage de la ligne de caractère se fait à l'aide des accolades {} et les macros print!() / println!() prennent un nombre d'arguments variables. A chaque {} doit correspondre une variable dont on veut afficher le contenu.

Il est également possible de numéroter chaque {}. Par exemple

#![allow(unused)]
fn main() {
println!("{1} {0}", "abc", "def");
}

Affichera def abc.

Rustlings

Les rustlings à faire dans ce chapitre sont les suivants:

Introduction

$ rustlings run intro1
$ rustlings run intro2

Les variables

$ rustlings run variables1
$ rustlings run variables2
$ rustlings run variables3
$ rustlings run variables4
$ rustlings run variables5

Les types primitifs

$ rustlings run primitive_types1
$ rustlings run primitive_types2
$ rustlings run primitive_types3