La correspondance de modèles est l'un des mécanismes linguistiques les plus importants en Rust, issu des langages fonctionnels. Elle permet de décomposer de manière déclarative, concise et sécurisée des variantes complexes de valeurs, y compris à l'aide de conditions supplémentaires (expressions guard), ce qui procure flexibilité et contrôle sur la logique.
Sans vérification d'exhaustivité, une partie des scénarios de puissance de la correspondance de modèles peut être réalisée avec des erreurs. De plus, sans compréhension de l'ordre des branches et des expressions guard, il est possible de se tromper soit dans la logique, soit dans la performance.
En Rust, le compilateur vérifie que toutes les variantes de l'enum (ou structures de modèles plus simples) sont traitées, ou qu'il y a une branche _. La branche peut être limitée par une expression guard (if après le modèle), et ne s'active que si la condition est remplie. Les variantes restantes ne sont pas capturées. L'ordre des branches est important : elles sont vérifiées de haut en bas.
Exemple de code :
enum Message { Hello, Data(i32), Quit, } fn handle(msg: Message) -> &'static str { match msg { Data(n) if n > 10 => "Big Data", Data(_) => "Some Data", Hello => "Greet!", Quit => "Bye", } }
Caractéristiques clés :
La branche avec guard s'active-t-elle si le modèle correspond, mais la condition n'est pas remplie ?
Non, dans ce cas, la vérification se poursuit vers la prochaine branche appropriée. Modèle + guard est un "filtre" atomique ; seulement lorsque les deux correspondent, le corps de la branche s'exécute.
L'ordre des branches dans le match affecte-t-il la performance ?
Oui. Surtout en cas d'abondance de modèles similaires avec guard : le compilateur vérifie les branches de haut en bas, ce qui influence la vitesse de vérification à l'exécution — les valeurs les plus rencontrées doivent être traitées en premier.
Peut-on ignorer la vérification d'exhaustivité en ne mettant qu'une branche _ ?
Techniquement oui — c'est permis, mais cela perd de la fiabilité : si le type exclut (ou ajoute) des nouveaux éléments, le compilateur ne préviendra pas d'un cas non traité. Il est toujours préférable de traiter explicitement les cas importants, et "_" n'est à utiliser qu'en dernier recours.
Code match pour un enum avec des expressions guard, où le modèle avec guard est en dernier, mais la plupart des valeurs passent directement par la branche précoce _, ne parvenant jamais au traitement nécessaire.
Avantages :
_.Inconvénients :
Les variantes les plus fréquentes et importantes sont d'abord énumérées (avec guard), puis le reste est couvert de manière exhaustive — sans code superflu dans "_".
Avantages :
Inconvénients :