ProgrammationDéveloppeur Rust

Comment fonctionne le pattern matching et le destructuring en Rust, et quelles subtilités doivent être prises en compte lors de leur utilisation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Le pattern matching en Rust permet de décomposer des valeurs selon leur structure, d'analyser et de traiter des types complexes à l'aide des constructions match, if let, while let. Le destructuring (décomposition) est pratique pour travailler avec des tuples, des structures, des enums et même des références.

Exemple avec un enum :

enum Message { Quit, ChangeColor(i32, i32, i32), Write(String), } let m = Message::ChangeColor(255, 0, 0); match m { Message::Quit => println!("Quit!"), Message::ChangeColor(r, g, b) => println!("Couleur : {} {} {}", r, g, b), Message::Write(text) => println!("Texte : {}", text), }

Destructuration de structures :

struct Point { x: i32, y: i32 } let p = Point { x: 10, y: 20 }; let Point { x, y } = p;

Subtilités :

  • L'utilisation de ref et ref mut permet d'obtenir des références lors de la décomposition.
  • Avec @, il est possible de "renommer" une partie du pattern.
  • Matching par valeurs, plages, conditions (if guard).
  • Lors du destructuring de références (&SomeType) — il est important de se souvenir de la propriété et du borrowing.

Question piège

Peut-on toujours utiliser "_" (souligné) pour ignorer des parties du pattern et éviter les avertissements du compilateur ?

Pas toujours. Le souligné ignore effectivement la valeur, mais si tous les cas d'un enum ne sont pas traités et que "_" est utilisé comme catch-all, vous pourriez rater le traitement de nouveaux cas lors de l'extension de l'enum à l'avenir. Il est préférable de toujours énumérer explicitement les cas importants pour que le compilateur avertisse des cas non traités !

match result { Ok(val) => ..., Err(err) => ..., //_ => ... // non recommandé pour les enums ! }

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


Histoire

Dans une application IoT, un appareil a cessé de répondre parce qu'en ajoutant une nouvelle variante à l'enum, un catch-all "_" était utilisé dans le pattern matching. L'erreur est restée invisible jusqu'au déploiement. Après cela, les enums critiques ont toujours été traités uniquement par un énumération explicite des variantes.


Histoire

Pour une structure complexe avec des tuples imbriqués, nous avons oublié d'ajouter la syntaxe de destructuration des champs récursifs, et au lieu d'obtenir des références, les codes ont accidentellement cloné de grands objets, ce qui a entraîné une baisse de performance.


Histoire

Dans une fonctionnalité de transmission de messages entre threads, nous avons utilisé la destructuration via if-let, mais avons ignoré les variantes rares de l'enum. Lorsque de nouvelles logiques métier sont apparues, les messages se perdaient simplement. Après cela, dans un esprit de collaboration, une règle a été établie — chaque expression match doit être exhaustive sans catch-all.