Musterabgleich
Match-Muster-Reihenfolge
Abschnitt betitelt „Match-Muster-Reihenfolge“enum Location { Point(i32), Range(i32, i32)}
fn main() { let l: Location = Location::Range(0, 5); let n = match l { Location::Point(_) => -1, Location::Range(_, 5) => 5, Location::Range(0, _) => 0, _ => -2 }; println!("{n}");}Jedes Match-Muster wird von oben nach unten geprüft. Sowohl das zweite als auch das dritte Muster sind anwendbar, daher wird das zweite verwendet.
Option unwrap_or
Abschnitt betitelt „Option unwrap_or“Betrachten Sie diese Methode, die für den Typ Option implementiert wurde:
impl<T> Option<T> { fn unwrap_or(self, other: T) -> T { match self { Some(t) => t, None => other } }}Welcher Satz beschreibt das Verhalten dieser Funktion am besten?
Diese Funktion “entpackt” die Option, indem sie deren Ownership konsumiert und den darin enthaltenen Wert abruft. Falls jedoch kein Wert existiert, greift sie auf die Rückgabe von other zurück.
Dies ist eine echte Funktion in der Standardbibliothek!
Ownership im Match
Abschnitt betitelt „Ownership im Match“#[derive(Debug)]enum Either { Left(usize), Right(String)}
fn main() { let x = Either::Right(String::from("Hello world")); let value = match x { Either::Left(n) => n, Either::Right(s) => s.len() }; println!("{x:?} {value}");}Der Match-Arm Either::Right(s) verschiebt das Feld s, daher kann x nicht im println! verwendet werden.
Match vs. If
Abschnitt betitelt „Match vs. If“Betrachten Sie diese beiden Implementierungen einer Funktion, um eine vorzeichenlose Zahl zweimal zu dekrementieren.
fn decr_twice_v1(n: u32) -> Option<u32> { match n { 0 => None, 1 => None, n2 => Some(n2 - 2) }}
fn decr_twice_v2(n: u32) -> Option<u32> { if n == 0 { None } else if n == 1 { None } else { Some(n - 2) }}Die Funktionen haben das gleiche Verhalten für:
Das match und das if erfüllen hier die gleiche Funktion. Ein match ist wie ein spezialisiertes if, das auf Gleichheit des abgeglichenen Objekts prüft.