Thanks!
X
Paypal
Github sponsorship
Patreon
Acheter version papier

Rust

Fork me on GitHub

I. Les bases de la programmation en Rust

4. Variables

La première chose à savoir en Rust est que toutes les variables sont constantes par défaut. Exemple :

Runlet i = 0;

i = 2; // Erreur !

Pour déclarer une variable mutable, il faut utiliser le mot-clé mut :

Runlet mut i = 0;

i = 2; // Ok !

4. Les types

Voyons maintenant comment fonctionnent les types en Rust. Ici, rien de nouveau par-rapport à ce que vous avez pu voir dans d'autres langages, on a toujours des entiers, des flottants, des strings, etc. La seule différence viendra surtout de leur nommage. Par exemple, pour déclarer un entier de 32 bits, vous écrirez :

Runlet i: i32 = 0;
// ou :
let i = 0i32;

Vous devez également savoir que le compilateur de Rust utilise l'inférence de type. Cela signifie qu'il peut déduire le type d'une variable en fonction de sa valeur. Nous ne sommes donc pas obligés de déclarer le type d'une variable. Exemple :

Run// On se met dans la peau de rustc :
// 0 est un entier donc i est un entier
let i = 0;
// 10 est un i32 alors max est un i32
let max = 10i32;

// < est capable de comparer deux nombres alors comme on sait que :
// max est un i32, donc le compilateur en déduit que i en est un aussi
if i < max {
    println!("i est inférieur à max !");
}

Voici une liste des différents types de base (aussi appelés "primitifs") disponibles :

  • i8 : un entier signé de 8 bits
  • i16 : un entier signé de 16 bits
  • i32 : un entier signé de 32 bits
  • i64 : un entier signé de 64 bits
  • i128 : un entier signer de 128 bits
  • u8 : un entier non-signé de 8 bits
  • u16 : un entier non-signé de 16 bits
  • u32 : un entier non-signé de 32 bits
  • u64 : un entier non-signé de 64 bits
  • u128 : un entier non-signé de 128 bits
  • f32 : un nombre flottant de 32 bits
  • f64 : un nombre flottant de 64 bits
  • str (on va y revenir plus loin dans ce chapitre)
  • slice (on va y revenir plus loin dans ce chapitre)

Sachez cependant que les types isize et usize existent aussi et sont l'équivalent de intptr_t et de uintptr_t en C/C++. En gros, sur un système 32 bits, ils feront respectivement 32 bits tandis qu'ils feront 64 bits sur un système 64 bits.

Dernier petit point à aborder : il est courant de croiser ce genre de code en C/C++/Java/etc... :

Runi++;
++i;

Cette syntaxe est invalide en Rust, il vous faudra donc utiliser :

Runi += 1;

Autre détail qui peut avoir son importance : si on fait commencer le nom d'une variable par un '_', nous n'aurons pas de warning du compilateur si elle est inutilisée. Ça a son utilité dans certains cas, bien que cela reste assez restreint. Exemple :

Runlet _i = 0;

Il est temps de revenir sur les slices.

Les slices

Pour faire simple, une slice représente un morceau de mémoire (on peut aussi dire que c'est un tableau). Pour ceux qui auraient fait du C/C++, c'est tout simplement un pointeur et une taille. Exemples :

Run// tab est une slice contenant 0, 1 et 2
let tab = &[0, 1, 2];
// ça affichera "[0, 1, 2]"
println!("{:?}", tab);

// s est maintenant une slice commençant à partir du 2e élément de tab
let s = &tab[1..];
// ça affichera "[1, 2]"
println!("{:?}", s);

De la même façon qu'il est possible d'obtenir une slice à partir d'une slice, on peut en obtenir à partir des Vecs (prononcer "vecteur") :

Runlet mut v = Vec::new();

v.push(0);
v.push(1);
v.push(2);
let s = &v;

// ça affichera "[0, 1, 2]"
println!("{:?}", s);
let s = &v[1..];

// ça affichera "[1, 2]"
println!("{:?}", s);

Les types contenant des tableaux ont toujours une slice associée. Par-exemple, String a &str, OsString a OsStr, etc...