Historique de la question
L'opérateur match en Rust est un puissant outil de correspondance de motifs emprunté aux langages fonctionnels. Contrairement aux équivalents en C/C++, Rust effectue une vérification stricte de la complétude (exhaustiveness checking), et chaque variante possible doit être couverte par une branche.
Problème
Les erreurs lors de l'utilisation de match sont souvent dues à un mauvais traitement de tous les cas de types (par exemple, enum), à une mauvaise gestion des gardes (conditions sur les branches) ou à une structure imbriquée complexe. Un traitement incorrect entraîne des erreurs à l'étape de compilation ou une logique fausse non détectée.
Solution
_).if après le motif).Exemple de code :
enum Shape { Circle(f64), Rectangle { width: f64, height: f64 }, } fn print_area(s: Shape) { match s { Shape::Circle(r) if r > 0.0 => println!("area = {}", 3.14 * r * r), Shape::Rectangle { width, height } if width > 0.0 && height > 0.0 => println!("area = {}", width * height), _ => println!("invalid shape"), } }
Caractéristiques clés :
L'ordre des branches dans match influence-t-il l'exécution ?
Oui, l'ordre des branches est important : dès qu'une correspondance est trouvée, les suivantes ne sont plus vérifiées. Cela est particulièrement critique avec pattern guard — si une branche avec garde est en premier, elle interceptera la valeur avant le catch-all.
Le catch-all (_) est-il obligatoire lors d'un match sur enum ?
Non, si vous avez explicitement couvert tous les cas (et que les variantes du type ne changeront pas dans le temps). Cependant, un catch-all est nécessaire lorsqu'il existe des types qui peuvent avoir des valeurs supplémentaires ou lorsque vous ne souhaitez pas traiter toutes les branches explicitement.
Peut-on utiliser plusieurs motifs (alternatives) dans une seule branche match ?
Oui. À l'aide de la barre verticale (|), vous pouvez combiner des motifs :
match x { 1 | 2 | 3 => println!("one, two or three"), _ => println!("something else"), }
_ trop tôt (avant les branches spécifiques).Le développeur a écrit un match avec un catch-all au début et n'a pas pu traiter correctement les cas spécifiques.
Avantages :
Le programme se compile.
Inconvénients :
La logique spécifique ne fonctionne jamais, une partie du code n'est pas couverte.
Traitement explicite de toutes les variantes d'enum, catch-all uniquement en dernière branche, gardes distinctes pour les cas atypiques.
Avantages :
Prévisibilité, le compilateur aide à ne pas oublier une variante, facile à étendre les types.
Inconvénients :
Code modèle supplémentaire en cas de nombreux cas.