Les fonctions en Rust
Une fonction est un bloc de code nommé et réutilisable. Au lieu de réécrire les mêmes étapes encore et encore, vous les placez une fois dans une fonction et vous l’appelez chaque fois que vous en avez besoin. Vous en utilisez déjà une : main.
Définir et appeler une fonction
Section intitulée « Définir et appeler une fonction »On définit une fonction avec fn, et on l’appelle en écrivant son nom suivi de () :
fn greet() { println!("Bonjour depuis une fonction !");}
fn main() { greet(); // on l'appelle greet(); // et on l'appelle encore}Sortie :
Bonjour depuis une fonction !Bonjour depuis une fonction !Les paramètres : donner des données à une fonction
Section intitulée « Les paramètres : donner des données à une fonction »Une fonction devient vraiment utile quand on lui passe des données sur lesquelles travailler. Ces entrées s’appellent des paramètres. En Rust, vous devez écrire le type de chaque paramètre :
fn greet(name: &str) { println!("Bonjour, {name} !");}
fn main() { greet("Alice"); greet("Bob");}Sortie :
Bonjour, Alice !Bonjour, Bob !Vous pouvez avoir autant de paramètres que nécessaire, séparés par des virgules :
fn describe(name: &str, age: u32) { println!("{name} a {age} ans");}
fn main() { describe("Ferris", 10);}Sortie :
Ferris a 10 ansLes valeurs que vous passez sont associées aux paramètres selon leur position : la première va dans name, la deuxième dans age. Si vous les passez dans le mauvais ordre, comme describe(10, "Ferris"), c’est une erreur de compilation, car les types ne correspondent pas.
Renvoyer une valeur
Section intitulée « Renvoyer une valeur »Une fonction peut renvoyer une valeur à celui qui l’a appelée. On déclare le type de retour après une flèche -> :
fn add(a: i32, b: i32) -> i32 { a + b}
fn main() { let sum = add(3, 4); println!("3 + 4 = {sum}");}Sortie :
3 + 4 = 7La règle du point-virgule (important !)
Section intitulée « La règle du point-virgule (important !) »Remarquez que a + b, dans l’exemple ci-dessus, n’a pas de point-virgule. C’est une idée clé de Rust :
- Une expression sans point-virgule est la valeur renvoyée.
- Ajouter un point-virgule la transforme en instruction qui ne renvoie rien.
Ceci est donc incorrect :
fn add(a: i32, b: i32) -> i32 { a + b; // ❌ le point-virgule veut dire « ne renvoie rien », mais on a promis un i32}Le compilateur va se plaindre que la fonction devrait renvoyer un i32 mais ne le fait pas. Il suffit d’enlever le point-virgule sur la dernière ligne.
Tout assembler
Section intitulée « Tout assembler »fn square(n: i32) -> i32 { n * n}
fn main() { let result = square(5); println!("5 au carré vaut {result}");}Sortie :
5 au carré vaut 25Exercices
Section intitulée « Exercices »1. Des Celsius aux Fahrenheit
Section intitulée « 1. Des Celsius aux Fahrenheit »Écrivez une fonction to_fahrenheit qui prend une température en degrés Celsius sous forme de f64 et la renvoie en degrés Fahrenheit. La formule est c * 9.0 / 5.0 + 32.0. Appelez-la pour 0, 100 et 37 degrés. Indice : la signature est fn to_fahrenheit(c: f64) -> f64, et le corps est une seule expression, sans point-virgule.
Voir la solution
fn to_fahrenheit(c: f64) -> f64 { c * 9.0 / 5.0 + 32.0}
fn main() { println!("0 °C font {} °F", to_fahrenheit(0.0)); println!("100 °C font {} °F", to_fahrenheit(100.0)); println!("37 °C font {} °F", to_fahrenheit(37.0));}Sortie :
0 °C font 32 °F100 °C font 212 °F37 °C font 98.6 °FRemarquez qu’on passe 0.0, et pas 0. Le paramètre est un f64, et Rust ne transforme pas un entier en nombre à virgule sans vous le dire. Quand un f64 n’a pas de partie décimale, {} l’affiche sans le .0 : c’est pour ça que vous voyez 32 et non 32.0. Notez aussi que Rust affiche toujours un point comme séparateur décimal (98.6), jamais une virgule.
2. Le plus grand des trois
Section intitulée « 2. Le plus grand des trois »Écrivez une fonction largest(a: i32, b: i32, c: i32) -> i32 qui renvoie le plus grand de ses trois nombres. Testez-la avec (3, 9, 4) et (-2, -8, -5). Indice : if est une expression en Rust (voir If…else), donc une chaîne if / else if / else peut être la dernière ligne de la fonction.
Voir la solution
fn largest(a: i32, b: i32, c: i32) -> i32 { if a >= b && a >= c { a } else if b >= c { b } else { c }}
fn main() { println!("{}", largest(3, 9, 4)); println!("{}", largest(-2, -8, -5));}Sortie :
9-2Aucune des branches ne se termine par un point-virgule. Chacune est une expression, la chaîne if entière renvoie l’une d’elles, et c’est elle qui devient la valeur de retour. Utiliser >= plutôt que > garantit qu’en cas d’égalité, on renvoie quand même une valeur.
Récapitulatif
Section intitulée « Récapitulatif »- On définit une fonction avec
fnet on l’appelle avecnom(). - Les paramètres sont les entrées ; chacun a besoin d’un type :
fn greet(name: &str). - On déclare un type de retour avec
-> Type. - La dernière expression sans point-virgule est la valeur renvoyée.
return valeur;fonctionne aussi, mais on le réserve en général aux retours anticipés.
Petit quiz
Section intitulée « Petit quiz »Petit quiz
1. En Rust, faut-il écrire le type de chaque paramètre d'une fonction ?
2. Comment déclare-t-on le type de retour d'une fonction ?
3. Pourquoi a + b (sans point-virgule) à la fin d'une fonction devient-il sa valeur de retour ?
4. Est-ce important de définir une fonction au-dessus ou en dessous de l'endroit où on l'appelle (par exemple, au-dessus ou en dessous de main) ?
Score : 0 / 4
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Functions — The Rust Book (en anglais) : le chapitre officiel sur les paramètres, les valeurs de retour et la différence entre instructions et expressions.
- Statements and Expressions — The Rust Book (en anglais) : un regard plus approfondi sur l’idée derrière la règle du point-virgule.
- Functions — Rust by Example (en anglais) : des exemples exécutables, dont le
returnanticipé et les fonctions qui ne renvoient rien. - Functions — The Rust Reference (en anglais) : les règles exactes de définition des fonctions, si vous voulez tous les détails.
- Le mot-clé
fn— documentation de la bibliothèque standard (en anglais) : un court résumé de la syntaxe des fonctions, avec des exemples.