ProgrammingRust Developer

How do pattern matching and destructuring work in Rust, and what nuances should be considered during their use?

Pass interviews with Hintsage AI assistant

Answer

Pattern matching in Rust allows breaking values down by structure, analyzing, and processing complex types using match, if let, while let constructs. Destructuring is convenient for working with tuples, structs, enums, and even references.

Example with 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!("Color: {} {} {}", r, g, b), Message::Write(text) => println!("Text: {}", text), }

Destructuring structs:

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

Nuances:

  • Using ref and ref mut allows obtaining references during destructuring.
  • With @, you can "rename" a part of the pattern.
  • Matching by values, ranges, conditions (if guard).
  • When destructuring references (&SomeType) — it's important to remember about ownership and borrowing.

Trick question

Can you always use "_" (underscore) to ignore parts of the pattern and avoid compiler warnings?

Not always. The underscore indeed skips the value, but if you don't handle all variants of an enum and use "_" for catch-all, you may miss handling new variants when extending the enum in the future. It's better to always explicitly list important variants so the compiler warns about unconsidered cases!

match result { Ok(val) => ..., Err(err) => ..., //_ => ... // not recommended for enum! }

Examples of real errors due to ignorance of topic nuances


Story

In an IoT application, the device stopped responding because when adding a new variant to the enum, a catch-all "_" was used in the pattern matching. The error remained hidden until deployment. After that, critical enums were always processed only with explicit listing of variants.


Story

For a complex structure with nested tuples, the syntax for destructuring recursive fields was forgotten, and instead of obtaining references, the codes accidentally cloned large objects, leading to performance degradation.


Story

In one functionality for message passing between threads, destructuring was used through if-let, but rare enum variants were ignored. With the introduction of new business logic, messages were simply lost. After that, a rule was established in the team style — every match expression must be exhaustive without catch-all.