Zum Inhalt springen

Musterabgleich

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}");
}
Erklärung anzeigen

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.


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?

Erklärung anzeigen

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!


#[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}");
}
Erklärung anzeigen

Der Match-Arm Either::Right(s) verschiebt das Feld s, daher kann x nicht im println! verwendet werden.


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:

Erklärung anzeigen

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.