Comment afficher le type d'une variable en Rust : 3 approches du débutant au pro

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

Comment afficher le type d'une variable en Rust sans perdre la tête

\n\n

Avez-vous déjà écrit du code en Rust et soudainement figé avec la question : "Mais quel est le type de cette variable ?" Si oui — vous n'êtes pas seul. La question "How do I print the type of a variable in Rust" sur Stack Overflow a recueilli des milliers de vues, et ce n'est pas un hasard. Rust est un langage avec un système de types strict mais intelligent, et parfois le compilateur en sait plus que nous.

\n\n

Dans cet article, nous allons explorer trois façons d'afficher le type d'une variable : de la simple astuce de débogage à la macro professionnelle. Vous apprendrez quand utiliser chaque méthode et cesserez de deviner quelle bête se cache derrière let x = ....

\n\n

Pourquoi Rust ne permet-il pas simplement d'imprimer le type ?

\n\n

Dans des langages comme Python ou JavaScript, vous pouvez écrire print(type(x)) — et voilà. Dans Rust, ce luxe n'existe pas pour deux raisons :

\n\n
    \n
  • Typage statique : les types sont connus à la compilation, mais ne sont pas toujours évidents pour le programmeur (surtout avec les closures ou les génériques complexes).
  • \n
  • Absence de réflexion : Rust ne stocke pas les informations de type à l'exécution par défaut — cela alourdirait les performances.
  • \n
\n\n

Mais les développeurs de Rust nous ont laissé quelques astuces. Regardons-les.

\n\n

Méthode 1 : std::any::type_name — la plus simple (mais pas idéale)

\n\n

La bibliothèque standard de Rust fournit la fonction std::any::type_name. Elle renvoie une chaîne avec le nom du type. Voici comment cela fonctionne :

\n\n
use std::any::type_name;\n\nfn print_type<T>(_: &T) {\n    println!("{}", type_name::<T>());\n}\n\nfn main() {\n    let x = 42;\n    let y = "hello";\n    let z = vec![1, 2, 3];\n    \n    print_type(&x); // i32\n    print_type(&y); // &str\n    print_type(&z); // Vec<i32>\n}
\n\n

Avantages :

\n
    \n
  • Minimum de code — fonctionne directement.
  • \n
  • Adapté au débogage et aux vérifications rapides.
  • \n
\n\n

Inconvénients :

\n
    \n
  • Le résultat dépend du compilateur : dans différentes versions de Rust ou sur différentes plateformes, la chaîne peut varier.
  • \n
  • Ne peut pas être utilisé dans une logique de production où des décisions doivent être prises en fonction du type.
  • \n
\n\n

Exemple concret : débogage d'une expression complexe

\n\n

Imaginez que vous travaillez avec des itérateurs et des chaînes de méthodes. Quel type obtiendrez-vous à la fin ?

\n\n
use std::any::type_name;\n\nfn main() {\n    let data = vec![1, 2, 3, 4, 5];\n    let result = data.iter()\n        .filter(|x| *x % 2 == 0)\n        .map(|x| x * 2)\n        .collect::<Vec<_>>();\n    \n    // Nous voulons connaître le type avant collect ?\n    let intermediate = data.iter()\n        .filter(|x| *x % 2 == 0)\n        .map(|x| x * 2);\n    \n    println!("Type de intermediate : {}", type_name::<decltype!(intermediate)>()); \n    // Oups, ça ne marchera pas — il faut passer une référence\n    println!("Type de intermediate : {}", type_name_of_val(&intermediate));\n}\n\nfn type_name_of_val<T>(_: &T) -> &str {\n    type_name::<T>()\n}
\n\n

Cette astuce vous sauvera lorsque le compilateur génère une erreur et que vous ne comprenez pas quel type il attend.

\n\n

Méthode 2 : Utiliser les erreurs du compilateur — une astuce maline

\n\n

Parfois, la meilleure façon de connaître le type est de forcer le compilateur à le révéler lui-même. Il existe une vieille astuce qui fonctionne toujours : assigner la variable à un type inexistant.

\n\n
fn main() {\n    let x = 42;\n    let y: () = x; // Erreur ! expected (), found i32\n}
\n\n

Le compilateur affichera quelque chose comme :

\n
error[E0308]: mismatched types\n --> src/main.rs:3:18\n  |\n3 |     let y: () = x;\n  |            --   ^ expected `()`, found `i32`\n  |            |\n  |            expected due to this
\n\n

Avantages :

\n
    \n
  • Ne nécessite pas d'imports.
  • \n
  • Fonctionne même dans des environnements sans std (no_st

Blogs

Book Recommendations