Aller au contenu

Rust - Variables et mutabilité

En Rust, on déclare des variables avec l'instruction let. Voici un exemple :

Rust
let nombre = 5

Cette ligne créée une variable nombre et lui assigne la valeur 5. Par défaut, les variables en rust sont immuable, ce qui veut dire que lorsqu'on assigne une valeur a une variable, elle ne pourra pas être modifiée. Pour faire une variable muable, on peut rajouter l'instruction `mut̀ avant le nom de la variable :

Rust
let mut nombre_muable = 12

Prenons maintenant le code suivant :

Rust
fn main() {
    let x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

Lorsqu'on essayera d'exécuter ce code, nous aurons l'erreur suivante :

Text Only
$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         -
  |         |
  |         first assignment to `x`
  |         help: consider making this binding mutable: `mut x`
3 |     println!("The value of x is: {x}");
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

For more information about this error, try `rustc --explain E0384`.
error: could not compile `variables` due to previous error

Cet exemple nous montre comment le compilateur nous aide a trouver les erreurs et les corriger. On a recu le message cannot assign twice to immutable variable étant donné qu'on a essayé de changer la valeur de x.

Comme on l'a dit précédamment, il suffit de rajouter mut a la 2ème ligne du programme.

Constantes

Comme les variables immuables, les constantes sont des valeurs attachées a un nom et ne sont pas autorisées a changer. Il y a cependant des différences.

La première est qu'il est impossible d'utiliser mut avec les constantes. Elles ne sont pas juste immuables par défaut, elles le sont tout le temps. Elles doivent également être déclarés avec le mot clé const et le type de la variable doit être spécifié. Voici un exemple :

Rust
const TROIS_HEURES_EN_SECONDES: u32 = 60 * 60 * 3

Les constantes ne peuvent pas êtres des valeurs calculés a l'exécution. Les valeurs des constantes sont calculées a la compilation. Le compileur est capable de comprendre différentes opérations a la compilation. Cela permet d'écrire la valeur dans un sens plus compréhensible, plutot que de la définir comme 10 800 (60 minutes * 60 secondes * 3 heures). La convention de nommage des constantes est de les écrire en majuscule avec des undrescores entre les mots.

Les constantes sont valides pendant l'entiereté du programe, dans l'espace ou elles sont déclarées. C'est assez utile lorsqu'un programme a besoin de la valeur plusieurs fois, comme par exemple le nombre maximum de points obtenable par un joueur dans un jeu ou la vitesse de la lumière. Utiliser les contantes rend le code également plus facile a maintenir.

Shadowing

Lorsqu'on programme en Rust, il est possible de déclarer une variable avec le même nom qu'une variable déja déclarée. Les Rustaciens disent que la première variable est shadowed par la deuxième, ce qui signifie que le compileur va lire la deuxième variable lorsqu'il va compiler et exécuter le programme. La variable est utilisée tant qu'elle est valide ou qu'elle est a nouveau shadowée. On peut shadower une variable en réutilisant un let comme dans cet example :

Rust
fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}

Le programme affecte d'abbord la valeur 5 a x. Il créée ensuite une nouvelle variable x en répêtant let x =, en prenant l'ancienne valeur et en lui ajoutant 1 ce qui donne 6. Ensuite, dans un nouveau champ, le troisième let créée une nouvelle variable x et la multiplie par deux, et affiche sa valeur dans le champ. Quand le champ est terminé, le shadowing du troisième let prend fin et x redevient 6.

Le shadowning est différent que la création d'une variable muable, vu qu'on obtiendrait une erreur si on essaye de réassigner une valeur sans let. Avec ce dernier, on peut effectuer quelques transformations sur une valeur tout en la rendant imuable après que les transformations sont faites.

Une autre esst le fait qu'on crée vraiment une nouvelle variable vu qu'on réutilise let. On peut donc changer le type de la variable en cours de route, tout en gardant le même nom. Par exemple, on peut créer un programme qui demande le nombre d'espace que l'utilisateur veut entre chaque mot d'une phrase. Voici un morceau de ce programme :

Rust
    let spaces = "   ";
    let spaces = spaces.len();

Le premier spaces est une variable de type string et le deuxième un nombre. Le shadowing nous évite de créer plusieurs variable et avoir à trouver des noms différent pour chaque variable, comme spaces_str et spaces_num. A la place, on peut simplement utiliser spaces. Cependant, si on essaye d'utiliser mut pour cette occasion, il y aura une erreur de compilation :

Rust
    let mut spaces = "   ";
    spaces = spaces.len();

L'erreur nous dit qu'il est impossible de muter le type d'une variable :

Text Only
$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
 --> src/main.rs:3:14
  |
2 |     let mut spaces = "   ";
  |                      ----- expected due to this value
3 |     spaces = spaces.len();
  |              ^^^^^^^^^^^^ expected `&str`, found `usize`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error