Variables et types de base

Lier une variable

En Rust, on ne déclare pas à proprement parler les variables, mais on les associe à une valeur avec le mot clef let. La ligne suivante crée une variable a qui va être liée à la valeur 3:

fn main() {
let a = 3;
println!("La valeur de a est {a}.");
}

Le type de a va être inféré par rapport à la valeur du litéral, ici un entier signé sur 32 bits (i32). On aurait pu également donner le type de manière explicite à la variable de la manière suivante:

fn main() {
let a:i64 = 3;
println!("La valeur de a est {a}.");
}

En Rust, une instruction let n'est pas une expression (à la différence de C/C++ ou l'affectation renvoie une valeur).

Types de données scalaires

Rust a les types scalaires classiques entiers, flottants, booléens et caractères.

Entiers (integers)

Les entiers sont les suivants:

LengthSignedUnsigned
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

Les entiers litéraux peuvent être définis avec les syntaxes suivantes:

Number literalsExample
Decimal98_222
Hex0xff
Octal0o77
Binary0b1111_0000
Byte (u8 only)b'A'

Un entier litéral sera par défaut en 32 bits (i32).

Flottants

Rust propose des flottants suivant le standard IEEE-754: simple précision f32 et double précision f64. Un litéral de type flottant comme 2.0 sera par défaut en double précision.

fn main() {
    let x = 2.0; // f64

    let y: f32 = 3.0; // f32
}

Booléens

Le type booléen (bool) supporte les deux valeurs littérales true et false.

fn main() {
    let t = true;

    let f: bool = false; // with explicit type annotation
}

Caractères

Les caractères en Rust sont sur quatre octets et contiennent des valeurs Unicode scalaires.

fn main() {
    let c = 'z';
    let z: char = 'ℤ'; // with explicit type annotation
    let heart_eyed_cat = '😻';
}

Opérations

fn main() {
    // addition
    let sum = 5 + 10;

    // subtraction
    let difference = 95.5 - 4.3;

    // multiplication
    let product = 4 * 30;

    // division
    let quotient = 56.7 / 32.2;
    let truncated = -5 / 3; // Results is -1
    println!("Truncated = {truncated}");
    
    // remainder
    let remainder = 43 % 5;
}

Synthèse

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}

fn main() {
    // Variables can be type annotated.
    let logical: bool = true;

    let a_float: f64 = 1.0;  // Regular annotation
    let an_integer   = 5i32; // Suffix annotation

    // Or a default will be used.
    let default_float   = 3.0; // `f64`
    let default_integer = 7;   // `i32`

    let a = 'a';
    let alpha = 'α';
    let inf = '∞';
    let z: char = 'ℤ';
    let heart_eyed_cat = '😻';

    // A type can also be inferred from context 
    let mut inferred_type = 12; // Type i64 is inferred from another line
    inferred_type = 4294967296i64;
    print_type_of(&inferred_type);
}