Arguments de fonction par défaut en Rust : des solutions élégantes sans surcharge

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi Rust n'a pas d'arguments par défaut — et comment contourner cela

\n\n

Si vous venez à Rust depuis Python, JavaScript ou C++, vous avez probablement été surpris : Rust n'a pas de support intégré pour les arguments par défaut. On ne peut pas simplement écrire fn greet(name = "monde") — le compilateur vous dira « non ».

\n\n

Mais ne vous découragez pas ! Rust propose d'autres approches, plus flexibles et plus sûres. Dans ce tutoriel, nous allons voir 3 méthodes éprouvées pour implémenter le comportement des arguments par défaut. Vous apprendrez à utiliser Option<T>, les structures de configuration et le pattern Builder — et quelle méthode choisir pour votre tâche.

\n\n

Cet article est basé sur une question réelle de Stack Overflow (plus de 50 000 vues) — nous l'avons adaptée pour un format éducatif. C'est parti !

\n\n

Méthode 1. Utiliser Option<T> — l'option la plus simple

\n\n

La méthode la plus directe consiste à accepter les arguments comme Option<T> et à substituer les valeurs par défaut à l'intérieur de la fonction.

\n\n
fn greet(name: Option<&str>) {\n    let name = name.unwrap_or("monde");\n    println!("Bonjour, {} !", name);\n}\n\nfn main() {\n    greet(Some("Anna")); // Bonjour, Anna !\n    greet(None);         // Bonjour, monde !\n}\n
\n\n

Avantages :

\n
    \n
  • Code minimal
  • \n
  • Compréhensible même pour un débutant
  • \n
  • Ne nécessite pas de structures supplémentaires
  • \n
\n\n

Inconvénients :

\n
    \n
  • Chaque appel nécessite d'encapsuler dans Some(...) ou None
  • \n
  • Si plusieurs paramètres — le code devient lourd
  • \n
\n\n

Cette approche convient parfaitement aux fonctions avec 1 à 2 paramètres optionnels. Mais s'ils sont plus nombreux, la lisibilité en souffre.

\n\n

Méthode 2. Structure de configuration — propre et évolutive

\n\n

Lorsque les paramètres deviennent 3, 5 ou 10, une structure de configuration vient à la rescousse. Vous créez un type séparé qui stocke tous les réglages, et vous implémentez le trait Default pour celui-ci.

\n\n
struct GreetConfig {\n    name: String,\n    greeting: String,\n    excitement_level: u8,\n}\n\nimpl Default for GreetConfig {\n    fn default() -> Self {\n        Self {\n            name: "monde".to_string(),\n            greeting: "Bonjour".to_string(),\n            excitement_level: 1,\n        }\n    }\n}\n\nfn greet(config: GreetConfig) {\n    let excitement = "!".repeat(config.excitement_level as usize);\n    println!("{}, {}{}", config.greeting, config.name, excitement);\n}\n\nfn main() {\n    // Utilisation des valeurs par défaut\n    greet(GreetConfig::default());\n    // Affichage : Bonjour, monde !\n\n    // Modification uniquement de ce qui est nécessaire\n    greet(GreetConfig {\n        name: "Anna".to_string(),\n        ..Default::default()\n    });\n    // Affichage : Bonjour, Anna !\n\n    // Appel entièrement personnalisé\n    greet(GreetConfig {\n        name: "Monde".to_string(),\n        greeting: "Salut".to_string(),\n        excitement_level: 3,\n    });\n    // Affichage : Salut, Monde !!!\n}\n
\n\n

Avantages :

\n
    \n
  • Flexibilité maximale
  • \n
  • Possibilité d'ajouter de nouveaux champs sans modifier la signature de la fonction
  • \n
  • La syntaxe ..Default::default() est très lisible
  • \n
\n\n

Inconvénients :

\n
    \n
  • Nécessite plus de code boilerplate
  • \n
  • Il faut implémenter explicitement le trait Default
  • \n
\n\n

C'est le choix idéal pour les projets réels : bibliothèques, fonctions de configuration, API complexes.

\n\n

Méthode 3. Pattern Builder — pour ceux qui aiment les chaînes

\n\n

Le pattern Builder est un classique de l'écosystème Rust. Vous créez une structure constructeur qui accumule les paramètres, et à la fin, vous appelez la méthode build().

\n\n
struct Greeter {\n    name: String,\n    greeting: String,\n    excitement_level: u8,\n}\n\nstruct GreeterBuilder {\n    nam                

Blogs

Book Recommendations