Introduction
Dans ce laboratoire, la fonctionnalité d'impression formatée en Rust est expliquée. Le module std::fmt fournit des macros telles que format!, print!, println!, eprint! et eprintln! pour gérer les tâches d'impression. Ces macros permettent de formater du texte avec des placeholders qui sont remplacés par les arguments correspondants. Des arguments positionnels et nommés peuvent être utilisés, et différentes formats peuvent être appliqués en utilisant des caractères de formatage. Les macros prennent également en charge la justification du texte, le rembourrage des nombres et la définition de la précision pour les nombres décimaux. Le trait fmt::Display est utilisé pour formater le texte d'une manière conviviale pour l'utilisateur, tandis que le trait fmt::Debug est utilisé à des fins de débogage. Rust vérifie également la correction du formatage à la compilation. De plus, il est mentionné que l'implémentation du trait fmt::Display implémente automatiquement le trait ToString, et que les types personnalisés doivent implémenter le trait fmt::Display pour être imprimables. Le laboratoire inclut également des activités pour pratiquer l'utilisation des macros et des traits d'impression formatée.
Note: Si le laboratoire ne spécifie pas de nom de fichier, vous pouvez utiliser n'importe quel nom de fichier que vous voulez. Par exemple, vous pouvez utiliser
main.rs, le compiler et l'exécuter avecrustc main.rs &&./main.
Impression formatée
L'impression est gérée par une série de macros définies dans std::fmt dont certaines sont les suivantes :
format!: écrit du texte formaté dans uneString.print!: identique àformat!mais le texte est imprimé sur la console (io::stdout).println!: identique àprint!mais un retour à la ligne est ajouté.eprint!: identique àprint!mais le texte est imprimé sur la sortie d'erreur standard (io::stderr).eprintln!: identique àeprint!mais un retour à la ligne est ajouté.
Toutes analysent le texte de la même manière. De plus, Rust vérifie la correction du formatage à la compilation.
fn main() {
// En général, `{}` sera automatiquement remplacé par n'importe quel
// argument. Ces arguments seront convertis en chaîne de caractères.
println!("{} jours", 31);
// On peut utiliser des arguments positionnels. Spécifier un entier à
// l'intérieur de `{}` détermine quel argument supplémentaire sera remplacé.
// Les arguments commencent à 0 immédiatement après la chaîne de formatage.
println!("{0}, c'est {1}. {1}, c'est {0}", "Alice", "Bob");
// On peut également utiliser des arguments nommés.
println!("{sujet} {verbe} {objet}",
objet="le chien paresseux",
sujet="le renard brun rapide",
verbe="saute par-dessus");
// On peut invoquer différents formats en spécifiant le caractère de format
// après un `:`.
println!("Base 10 : {}", 69420); // 69420
println!("Base 2 (binaire) : {:b}", 69420); // 10000111100101100
println!("Base 8 (octale) : {:o}", 69420); // 207454
println!("Base 16 (hexadécimale) : {:x}", 69420); // 10f2c
println!("Base 16 (hexadécimale) : {:X}", 69420); // 10F2C
// On peut justifier le texte à droite avec une largeur spécifiée. Cela
// produira " 1". (Quatre espaces blancs et un "1", pour une largeur totale de 5.)
println!("{nombre:>5}", nombre=1);
// On peut remplir les nombres avec des zéros supplémentaires,
println!("{nombre:0>5}", nombre=1); // 00001
// et ajuster à gauche en inversant le signe. Cela produira "10000".
println!("{nombre:0<5}", nombre=1); // 10000
// On peut utiliser des arguments nommés dans le spécificateur de format en
// ajoutant un `$`.
println!("{nombre:0>largeur$}", nombre=1, largeur=5);
// Rust vérifie même pour s'assurer qu'on utilise le bon nombre d'arguments.
println!("Mon nom est {0}, {1} {0}", "Bond");
// FIXME ^ Ajoutez l'argument manquant : "James"
// Seuls les types qui implémentent fmt::Display peuvent être formatés avec `{}`.
// Les types définis par l'utilisateur n'implémentent pas fmt::Display par défaut.
#[allow(dead_code)] // désactive `dead_code` qui avertit contre les modules inutilisés
struct Structure(i32);
// Cela ne compilera pas car `Structure` n'implémente pas
// fmt::Display.
// println!("Cette structure `{}` ne s'imprimera pas...", Structure(3));
// TODO ^ Essayez de décommenter cette ligne
// Pour Rust 1.58 et supérieur, vous pouvez directement capturer l'argument
// à partir d'une variable environnante. Comme ci-dessus, cela produira
// " 1", 4 espaces blancs et un "1".
let nombre: f64 = 1.0;
let largeur: usize = 5;
println!("{nombre:>largeur$}");
}
std::fmt contient de nombreux traits qui gèrent l'affichage du texte. Les formes de base de deux d'entre eux importants sont listées ci-dessous :
fmt::Debug: utilise le marqueur{:?}. Formate le texte à des fins de débogage.fmt::Display: utilise le marqueur{}. Formate le texte d'une manière plus élégante et conviviale pour l'utilisateur.
Ici, nous avons utilisé fmt::Display car la bibliothèque standard fournit des implémentations pour ces types. Pour imprimer du texte pour des types personnalisés, des étapes supplémentaires sont nécessaires.
L'implémentation du trait fmt::Display implémente automatiquement le trait ToString qui nous permet de convertir le type en String.
À la ligne 43, #[allow(dead_code)] est un [attribut] qui ne s'applique qu'au module qui le suit.
Activités
- Corrigez le problème dans le code ci-dessus (voir FIXME) pour qu'il s'exécute sans erreur.
- Essayez de décommenter la ligne qui tente de formater la structure
Structure(voir TODO) - Ajoutez un appel à la macro
println!qui imprime :Pi est environ 3,142en contrôlant le nombre de décimales affichées. Pour cet exercice, utilisezlet pi = 3,141592comme estimation de pi. (Indice : vous devrez peut-être consulter la documentation destd::fmtpour définir le nombre de décimales à afficher)
Sommaire
Félicitations ! Vous avez terminé le laboratoire d'impression formatée. Vous pouvez pratiquer d'autres laboratoires sur LabEx pour améliorer vos compétences.