Tutoriels gratuits et ouverts à toutes et à tous · conçus au Lycée Chevrollier — AngersÀ propos

Série « Parcours Rust » · partie 1 / 8

Rust niveau 0 — Découvrir Rust et Cargo

Installer la chaîne d’outils, écrire ses premiers programmes et apprendre à lire le compilateur : niveau 0 du parcours Rust, avec exercices corrigés et QCM.

Développement✎ B. Jousseaume📅 17 octobre 2026⏱ 3 h📶 Débutant

1. Qu’est-ce que Rust ?

Un programme est une suite d’instructions écrites dans un langage de programmation, puis traduites pour que le processeur les exécute. Deux grandes familles existent. Les langages interprétés, comme Python ou PowerShell, sont traduits au fil de l’exécution. Les langages compilés, comme C, C++ ou Rust, sont traduits une fois pour toutes en un fichier exécutable par un programme appelé compilateur.

Rust est un langage compilé, créé chez Mozilla et stable depuis 2015. Il vise un objectif longtemps jugé impossible : être aussi rapide que le C, tout en empêchant les erreurs de mémoire qui sont à l’origine d’une grande partie des failles de sécurité.

PythonRust
ExécutionInterprétéCompilé en exécutable natif
TypesVérifiés pendant l’exécutionVérifiés à la compilation
MémoireRamasse-miettes automatiqueRègles de possession vérifiées à la compilation
ErreursSouvent découvertes en exécutantMajoritairement détectées avant l’exécution
VitesseCorrecteComparable au C
Courbe d’apprentissageDoucePlus raide au début

On trouve Rust dans les outils en ligne de commande, les serveurs web, les systèmes embarqués, les navigateurs, et désormais dans le noyau Linux et certains composants de Windows.

2. Installer Rust

Rust s’installe avec rustup, le gestionnaire officiel, qui installe le compilateur rustc, le gestionnaire de projets cargo et la documentation.

  1. Va sur le site officiel rustup.rs, et uniquement celui-là.
  2. Sous Windows : télécharge et lance rustup-init.exe. Le programme propose d’installer les outils de compilation C++ de Microsoft (Visual Studio Build Tools) : accepte, Rust en a besoin.
  3. Sous Linux ou macOS : le site affiche une commande à coller dans un terminal. Lis d’abord l’encadré sécurité ci-dessous.
  4. Ferme puis rouvre le terminal, et vérifie l’installation :
$ rustc --version
rustc 1.xx.0 (...)
$ cargo --version
cargo 1.xx.0 (...)
$ rustup update          # pour mettre à jour plus tard

Pour écrire le code, installe Visual Studio Code avec l’extension rust-analyzer : elle souligne les erreurs pendant la frappe, affiche les types déduits et complète le code.

3. Premier projet avec Cargo

Cargo crée les projets, les compile, les exécute, télécharge les bibliothèques et lance les tests. En pratique, on n’appelle presque jamais rustc directement.

$ cargo new bonjour
    Creating binary (application) `bonjour` package
$ cd bonjour
$ cargo run
   Compiling bonjour v0.1.0
    Finished dev [unoptimized + debuginfo] target(s)
     Running `target/debug/bonjour`
Hello, world!

Cargo a créé cette arborescence :

bonjour/
├── Cargo.toml        ← la fiche d'identité du projet
└── src/
    └── main.rs       ← le code source

Le fichier src/main.rs contient déjà un programme complet :

fn main() {
    println!("Hello, world!");
}
  • fn main() déclare la fonction principale : c’est par elle que le programme commence.
  • Les accolades { } délimitent le corps de la fonction.
  • println! affiche une ligne. Le point d’exclamation signale une macro et non une fonction ordinaire ; tu n’as pas besoin d’en savoir plus pour l’instant.
  • Chaque instruction se termine par un point-virgule.
CommandeEffet
cargo new nomCrée un nouveau projet
cargo runCompile si nécessaire, puis exécute
cargo checkVérifie le code sans produire d’exécutable (le plus rapide)
cargo buildCompile en mode développement dans target/debug/
cargo build --releaseCompile en mode optimisé dans target/release/
cargo fmtRemet en forme le code selon le style officiel
cargo clippyAnalyse le code et suggère des améliorations

4. Afficher avec println!

Les accolades {} dans le texte sont remplacées par des valeurs. On peut y écrire directement un nom de variable.

fn main() {
    let prenom = "Lina";
    let age = 19;
    let moyenne = 14.567;

    println!("Bonjour {}, tu as {} ans.", prenom, age);   // valeurs dans l'ordre
    println!("Bonjour {prenom}, tu as {age} ans.");        // noms dans les accolades
    println!("Moyenne : {:.2}", moyenne);                  // 2 décimales
    println!("[{:>8}]", prenom);                           // aligné à droite sur 8 caractères
    println!("[{:<8}]", prenom);                           // aligné à gauche
    println!("[{:^8}]", prenom);                           // centré
    println!("{:05}", age);                                // complété par des zéros : 00019
    println!("Débogage : {:?}", (prenom, age));            // affichage technique
    eprintln!("Ce message part sur la sortie d'erreur");
}
ÉcritureEffetExemple de résultat
{}Valeur affichée normalementLina
{nom}Variable nommée directementLina
{:.2}Nombre à 2 décimales14.57
{:>8} {:<8} {:^8}Alignement à droite, à gauche, centré[ Lina]
{:05}Largeur 5 complétée par des zéros00019
{:?}Affichage de débogage("Lina", 19)

Les lignes qui commencent par // sont des commentaires : le compilateur les ignore.

5. Variables, immutabilité et masquage

Une variable se déclare avec let. Le type est le plus souvent déduit par le compilateur. Surprise pour qui vient d’un autre langage : une variable est immuable par défaut.

fn main() {
    let x = 5;
    println!("x vaut {x}");
    x = 6;
    println!("x vaut {x}");
}

Le compilateur refuse ce programme :

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!("x vaut {x}");
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

Pour autoriser la modification, on l’annonce avec mut :

fn main() {
    let mut compteur = 0;
    compteur = compteur + 1;
    compteur += 1;                 // écriture raccourcie
    println!("compteur = {compteur}");

    let age: u32 = 17;             // type écrit explicitement
    const TVA: f64 = 0.20;         // constante : type obligatoire, jamais modifiable
    const MAX_ESSAIS: u32 = 7;
    println!("{age} {TVA} {MAX_ESSAIS}");
}

Le masquage (shadowing)

On peut redéclarer une variable avec le même nom : la nouvelle masque l’ancienne. C’est différent de mut : on crée une nouvelle variable, qui peut même changer de type.

fn main() {
    let saisie = "42";                              // du texte
    let saisie: i32 = saisie.parse().unwrap_or(0);  // converti en nombre, même nom
    let x = 5;
    let x = x * 2;                  // 10
    {
        let x = x + 1;              // 11, seulement dans ce bloc
        println!("dans le bloc : {x}");
    }
    println!("après le bloc : {x}, saisie : {saisie}");  // 10
}

6. Lire les messages du compilateur

Un message d’erreur de Rust se lit toujours de la même façon :

ÉlémentRôle
error[E0384]Le type d’erreur et son code
--> src/main.rs:4:5Le fichier, la ligne et la colonne
^^^^^Ce qui est souligné est l’endroit exact du problème
help:Une correction proposée, souvent directement applicable
note:Une explication complémentaire

Pour une explication détaillée avec exemples : rustc --explain E0384.

Les avertissements (warning) n’empêchent pas la compilation, mais signalent un problème probable : variable inutilisée, mut inutile… Une variable volontairement inutilisée se préfixe par _ : let _brouillon = 3;.

7. Mini-projet : le ticket de caisse

8. Bilan

Exercices corrigés

À ce niveau, l’essentiel est de réussir à compiler et à lire les messages du compilateur. Si ton programme affiche le bon résultat avec une écriture différente de celle du corrigé, c’est parfait.

Exercice 0.1 — Premier projet

Voir le corrigé
$ cargo new carte_visite
$ cd carte_visite
fn main() {
    println!("------------------------------");
    println!("Lina Martin");
    println!("BTS SIO option SLAM");
    println!("Angers");
    println!("------------------------------");
}
$ cargo run
$ cargo build --release
$ ./target/release/carte_visite          # Linux, macOS
> .\target\release\carte_visite.exe      # Windows

Explication

Le mode --release active les optimisations : la compilation est plus lente, l’exécutable plus rapide et plus petit. C’est ce mode que l’on livre. Le mode par défaut, plus rapide à compiler, sert pendant le développement.

Exercice 0.2 — Variables

Voir le corrigé

1. Le programme affiche dans le bloc : 11 puis après le bloc : 10, saisie : 42. Le x du bloc n’existe que dans ses accolades.

fn main() {
    // 2.
    let longueur = 12.5;
    let largeur = 4.0;
    let aire = longueur * largeur;
    let perimetre = 2.0 * (longueur + largeur);
    println!("Aire : {aire:.2}  Périmètre : {perimetre:.2}");

    // 3.
    let mut compteur = 0;
    compteur += 1;
    compteur += 1;
    compteur += 1;
    println!("Compteur : {compteur}");

    // 4.
    const ANNEE_SCOLAIRE: u32 = 2026;
    println!("Année scolaire {}-{}", ANNEE_SCOLAIRE, ANNEE_SCOLAIRE + 1);
}

Explication

On peut combiner un nom de variable et un format dans les accolades : {aire:.2}. Sans mut, la ligne compteur += 1 provoque l’erreur E0384 vue dans le cours.

Exercice 0.3 — Déboguer avec le compilateur

Voir le corrigé
// A : il manquait le point-virgule (erreur "expected `;`")
fn main() {
    let total = 10;
    println!("{total}");
}
// B : on ne mélange pas f64 et entier (erreur E0277)
fn main() {
    let prix = 12.5;
    let quantite = 3.0;          // ou : let montant = prix * quantite as f64;
    let montant = prix * quantite;
    println!("{montant}");
}
// C : faute de frappe (erreur E0425) et variable inutilisée (avertissement)
fn main() {
    let nom = "Sam";
    println!("Bonjour {nom}");
}

Explication

Pour B, le message indique qu’il n’existe pas de multiplication entre {float} et {integer}. Rust ne convertit jamais un type numérique en un autre sans qu’on le demande : c’est une protection contre les pertes de précision silencieuses. Pour C, le compilateur propose même le bon nom : help: a local variable with a similar name exists: nom.

Mini-projet

Voir le corrigé
fn main() {
    const TVA: f64 = 0.20;

    let nom1 = "Cahier A4";
    let prix1 = 2.40;
    let qte1 = 5.0;

    let nom2 = "Stylo bleu";
    let prix2 = 0.85;
    let qte2 = 12.0;

    let nom3 = "Clé USB 32 Go";
    let prix3 = 7.90;
    let qte3 = 2.0;

    let st1 = prix1 * qte1;
    let st2 = prix2 * qte2;
    let st3 = prix3 * qte3;
    let total_ht = st1 + st2 + st3;
    let montant_tva = total_ht * TVA;
    let total_ttc = total_ht + montant_tva;

    println!("{}", "=".repeat(34));
    println!("{:<15} {:>4} {:>12}", "Article", "Qté", "Sous-total");
    println!("{}", "-".repeat(34));
    println!("{:<15} {:>4} {:>12.2}", nom1, qte1, st1);
    println!("{:<15} {:>4} {:>12.2}", nom2, qte2, st2);
    println!("{:<15} {:>4} {:>12.2}", nom3, qte3, st3);
    println!("{}", "-".repeat(34));
    println!("{:<20} {:>12.2}", "Total HT", total_ht);
    println!("{:<20} {:>12.2}", "TVA 20 %", montant_tva);
    println!("{:<20} {:>12.2}", "Total TTC", total_ttc);
    println!("{}", "=".repeat(34));
}

Explication

Les formats {:<15} et {:>12.2} font tout le travail de mise en page. "=".repeat(34) construit une ligne de 34 signes égal. Les quantités sont écrites 5.0 pour pouvoir être multipliées par des prix décimaux.

Pour aller plus loin

Au niveau 3, tu regrouperas nom, prix et quantité dans une structure, et au niveau 1 tu apprendras à éviter la répétition avec une boucle.

🧠 Testez vos connaissances

5 questions. Répondez puis cliquez sur « Corriger ». Rien n’est enregistré : c’est de l’auto-évaluation.

1. Que fait un compilateur ?

💬 C’est la différence avec un langage interprété comme Python. En Rust, beaucoup d’erreurs sont détectées à cette étape, avant toute exécution.

2. Quelle commande vérifie le code le plus rapidement, sans produire d’exécutable ?

💬 cargo check fait toutes les vérifications du compilateur sans générer de binaire : c’est la commande à lancer souvent.

3. Que se passe-t-il avec let x = 5; x = 6; ?

💬 Les variables sont immuables par défaut. Il faut écrire let mut x = 5; pour pouvoir la modifier.

4. Pourquoi le point d’exclamation dans println! ?

💬 Le ! signale une macro. Le retour à la ligne vient du ln de println ; print! n’en ajoute pas.

5. Tu clones un projet Rust inconnu. Pourquoi être prudent avant cargo build ?

💬 Les scripts de compilation et certaines dépendances s’exécutent pendant la compilation. Un projet douteux se compile dans une machine virtuelle.

© 2026 Bruno Jousseaume. Ce cours est publié sous licence CC BY-NC-SA 4.0 : vous pouvez le partager et l’adapter en citant l’auteur et un lien vers cette page, sans usage commercial, et en partageant vos adaptations sous la même licence.

Pour aller plus loin

Python niveau 1 — Premiers pas

Afficher, calculer, mémoriser dans des variables et dialoguer avec l’utilisateur : niveau 1 du parcours Python, avec exercices corrigés et QCM.

Débutant⏱ 4 à 5 h · 17 octobre 2026