Les fonctions sont des blocs de code contenant une ou plusieurs instructions ou expressions. Une fonction peut éventuellement renvoyer une valeur.
En Rust, la convention est d'utiliser le snake_case pour le nom d'une fonction, précédé du mot-clé fn pour la définition d'une fonction. Par exemple
fn do_nothing() {}
Les parenthèses entourent zéro ou plusieurs paramètres, séparés par des virgules. Un paramètre est une liaison à une valeur d'un type particulier qui est passée à la fonction. Même s'il n'y a aucun paramètre, les parenthèses restent obligatoires dans la définition de la fonction. La valeur réellement passée à un paramètre s'appelle un argument.
La combinaison des paramètres et de la valeur de retour constitue la signature de la fonction. La signature d'une fonction exige que le type de chaque paramètre soit annoté.
Les accolades délimitent le corps de la fonction : ses instructions et ses expressions. Même si la fonction ne contient aucune instruction ni expression, les accolades restent obligatoires dans la définition de la fonction.
Dans l'exemple suivant, la fonction prend un paramètre de type i32, le lie au nom value et l'affiche.
fn print_integer(value: i32) {
println!("{value:?}");
}
Remarque la définition du paramètre. Chaque paramètre est défini au format name: Type.
Une fonction peut aussi renvoyer une valeur. Par défaut, c'est le résultat de la dernière expression qui est renvoyé. Dans l'exemple suivant, la fonction prend un paramètre de type i32 et renvoie son double.
fn double_integer(value: i32) -> i32 {
value * 2
}
Le -> i32 indique que la fonction renvoie un i32. Contrairement aux paramètres, la valeur renvoyée n'a pas de nom.
Il est possible de sortir d'une fonction de façon anticipée avec le mot-clé return, comme ceci :
fn long_function() -> i32 {
let some_condition = false;
// code snipped
if (some_condition) {
return 0;
}
// more code snipped
42
}
const fn sert à définir une fonction constante, qui peut être évaluée à la compilation.
const fn compute_data_checksum() -> u128 {
const DATA: &[u8] = include_bytes!("my_big_data_file");
// checksum implementation is left as an exercise for the reader
}
/// This checksum is used to validate that the user has not tampered with proprietary configuration.
pub const DATA_CHECKSUM: u128 = compute_data_checksum();
Comme les fonctions constantes peuvent être évaluées à la compilation, elles ont certaines restrictions que les fonctions normales n'ont pas. En particulier, une const fn ne peut appeler que d'autres fonctions également marquées const. Ne pas respecter cette restriction provoque une erreur de compilation.
const fn multiply_integer(value: i32) -> i32 {
use std::time::SystemTime;
if SystemTime::now().elapsed().unwrap().as_nanos() == 0 { // this line errors
value * 2
} else {
value * 3
}
}
Il existe des fonctions anonymes, qui sont abordées dans le thème closures.