Rust - Variables et mutabilité
En Rust, on déclare des variables avec l'instruction let. Voici un exemple :
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 :
let mut nombre_muable = 12
Prenons maintenant le code suivant :
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 :
$ 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 :
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 :
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 :
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 :
let mut spaces = " ";
spaces = spaces.len();
L'erreur nous dit qu'il est impossible de muter le type d'une variable :
$ 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