ProgrammatieRust ontwikkelaar

Hoe werken pattern matching en destructuring in Rust, en welke nuances moeten in overweging worden genomen bij het gebruik ervan?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Pattern matching in Rust maakt het mogelijk om waarden op structuur te splitsen, complexe typen te analyseren en te verwerken met behulp van constructies zoals match, if let, while let. Destructurering (opdelen in delen) is handig voor het werken met tuples, structuren, enums en zelfs verwijzingen.

Voorbeeld met 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), }

Destructurering van structuren:

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

Nuances:

  • Het gebruik van ref en ref mut maakt het mogelijk om verwijzingen te krijgen bij het splitsen.
  • Met @ kan een deel van het patroon "hernoemd" worden.
  • Matching op waarden, intervallen, condities (if guard).
  • Bij destructurering van verwijzingen (&SomeType) is het belangrijk om eigendom en borrowing te onthouden.

Misleidende vraag

Kan "_" (onderstreping) altijd worden gebruikt om delen van een patroon te negeren en compiler waarschuwingen te vermijden?

Niet altijd. Onderstreping negeert inderdaad een waarde, maar als niet alle opties van de enum worden verwerkt en "_" wordt gebruikt als catch-all, kun je nieuwe opties mislopen bij het uitbreiden van de enum in de toekomst. Het is beter om altijd expliciet belangrijke opties op te sommen, zodat de compiler kan waarschuwen voor onbeschouwde gevallen!

match result { Ok(val) => ..., Err(err) => ..., //_ => ... // niet aanbevolen voor enum! }

Voorbeelden van reële fouten door gebrek aan kennis over nuances van het onderwerp


Verhaal

In een IoT-applicatie stopte het apparaat met reageren omdat een nieuwe optie in de enum was toegevoegd met catch-all "_" in plaats van expliciet alle opties te behandelen. De fout bleef onopgemerkt tot de uitrol. Na dit voorval werden kritische enums altijd alleen expliciet behandeld met een drievoudig patroon.


Verhaal

Voor een complexe structuur met geneste tuples werd de syntax van destructurering van recursieve velden vergeten, en in plaats van verwijzingen te verkrijgen, klonen de codes per ongeluk grote objecten, wat leidde tot prestatieverlies.


Verhaal

In een functie voor het verzenden van berichten tussen threads werd destructurering via if-let gebruikt, maar werden zeldzame opties van de enum genegeerd. Bij het verschijnen van nieuwe bedrijfslogica gingen berichten gewoon verloren. Na dit voorval werd het in het team vastgesteld als regel dat elk match-expressie volledig moet zijn zonder catch-all.