Aller au contenu

La syntaxe de Rust

Maintenant que vous savez lancer du Rust, prenons le temps de voir ce que signifie vraiment chaque partie d’un programme. Nous allons partir du plus petit exemple possible et le démonter pièce par pièce.

fn main() {
println!("Bonjour, le monde !");
}

Sortie :

Bonjour, le monde !
▶ Essayez par vous-même
fn main() {
// votre code s'exécute ici
}

Tout programme Rust démarre dans une fonction appelée main. Quand vous lancez votre programme, Rust cherche main et exécute le code qu’elle contient.

  • fn est le mot-clé qui sert à définir une fonction (un bloc de code qui porte un nom).
  • main est le nom de la fonction. Ce nom-là est spécial : c’est le point d’entrée du programme.
  • () contient les entrées de la fonction (ici, rien : main n’en prend aucune).
  • Les accolades { } entourent le corps de la fonction, c’est-à-dire le code qui lui appartient.

Les instructions se terminent par un point-virgule

Section intitulée « Les instructions se terminent par un point-virgule »

Dans le corps, chaque consigne est en général une instruction (statement), et les instructions se terminent par un point-virgule ; :

fn main() {
let x = 5;
let y = 10;
println!("{}", x + y);
}

Sortie :

15
▶ Essayez par vous-même

Oublier un point-virgule là où il en faut un, c’est l’une des erreurs de débutant les plus courantes, et le compilateur vous montrera précisément l’endroit.

Le code Rust est fait de deux sortes de morceaux, et la différence compte plus en Rust que dans la plupart des langages :

  • Une instruction (statement) fait quelque chose mais ne renvoie aucune valeur. let x = 5; est une instruction.
  • Une expression produit une valeur. 5, x + 1 et x * 2 sont toutes des expressions.

Voici ce qui surprend souvent : un bloc de code entre accolades { } est lui aussi une expression. Sa valeur, c’est sa dernière ligne, écrite sans point-virgule :

fn main() {
let x = 5;
let y = {
let doubled = x * 2; // une instruction dans le bloc
doubled + 1 // pas de point-virgule : c'est la valeur du bloc
};
println!("y vaut {y}");
}

Sortie :

y vaut 11
▶ Essayez par vous-même

Le bloc exécute ses instructions, puis renvoie doubled + 1, c’est-à-dire 11, et cette valeur devient y. Remarquez le point-virgule après l’accolade fermante } : la ligne entière let y = ...; reste une instruction.

Si vous ajoutez un point-virgule après doubled + 1, ce n’est plus la valeur du bloc. Le bloc renvoie alors « rien » (Rust l’écrit ()), que println! ne sait pas afficher, et le code ne compile pas. Cette règle du « pas de point-virgule sur la dernière ligne » est exactement la façon dont les fonctions renvoient des valeurs. Vous la retrouverez dans la page sur les fonctions et avec if utilisé comme expression.

Regardez bien println! : ce point d’exclamation n’est pas une faute de frappe. Le ! indique que c’est une macro, et non une fonction ordinaire.

Pas besoin de tout comprendre des macros pour l’instant. Retenez juste ceci : quand vous voyez un !, c’est une macro. Pour le moment, la seule que vous utiliserez est println!, pour afficher du texte.

fn main() {
println!("Ceci est un appel de macro");
}

Dans println!, les accolades {} sont des emplacements (placeholders) qui sont remplis par les valeurs que vous passez après le texte :

fn main() {
let name = "Ferris";
let age = 10;
println!("{} a {} ans", name, age);
}

Sortie :

Ferris a 10 ans
▶ Essayez par vous-même

Vous pouvez aussi mettre le nom de la variable directement entre les accolades, ce qui est souvent plus lisible :

println!("{name} a {age} ans");

Contrairement à Python, Rust ne se soucie pas de l’indentation : il utilise les accolades { } pour savoir où les blocs commencent et se terminent. L’indentation sert seulement aux humains, pour lire le code plus facilement.

Cela dit, la communauté a un style standard, et Rust fournit un outil pour l’appliquer automatiquement :

Terminal window
cargo fmt

Lancer cargo fmt remet en forme votre code selon le style officiel. Prenez l’habitude de l’utiliser.

Vous pouvez laisser dans votre code des notes que Rust ignore. Ce sont des commentaires, et ils commencent par // :

fn main() {
// Ceci est un commentaire : Rust l'ignore
println!("Bonjour !"); // un commentaire peut aussi se placer en fin de ligne
}

Nous verrons les commentaires plus en détail à la page suivante.

Créez deux variables, a = 7 et b = 3, et affichez 7 + 3 = 10. Laissez Rust faire l’addition. Indice : un println! peut contenir plusieurs emplacements {}, remplis dans l’ordre par les valeurs placées après le texte.

Voir la solution
fn main() {
let a = 7;
let b = 3;
println!("{} + {} = {}", a, b, a + b);
}

Sortie :

7 + 3 = 10
▶ Essayez par vous-même

Une boutique vend 3 articles à 4 l’unité, plus 2 de frais de port. Calculez total avec un bloc { } : à l’intérieur, créez un subtotal, puis renvoyez subtotal + 2. Affichez Total : 14. Indice : la dernière ligne du bloc ne doit pas avoir de point-virgule.

Voir la solution
fn main() {
let price = 4;
let quantity = 3;
let total = {
let subtotal = price * quantity;
subtotal + 2 // frais de port
};
println!("Total : {total}");
}

Sortie :

Total : 14
▶ Essayez par vous-même
  • Tout programme commence dans la fonction main.
  • Le code se trouve entre accolades { } ; la plupart des instructions se terminent par ;.
  • Les instructions font quelque chose ; les expressions produisent une valeur. La dernière ligne d’un bloc, sans ;, est sa valeur.
  • Un ! (comme dans println!) indique une macro.
  • Les {} dans println! sont des emplacements remplis par les valeurs que vous passez.
  • L’indentation sert à la lisibilité : lancez cargo fmt pour formater automatiquement.

Petit quiz

1. Qu’est-ce que la fonction main a de spécial dans un programme Rust ?

2. Que signifie le ! après println ?

3. Quelle est la valeur de y après let y = { let a = 2; a + 1 }; ?

Score : 0 / 3