add enum / testing example
parent
94df03a758
commit
746558c2ad
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Jede Variante kann unterschiedliche Daten tragen.
|
||||||
|
enum Tier {
|
||||||
|
Hund(String), // Tupel-Variante: Name
|
||||||
|
Fisch { art: String, liter: u32 }, // Struct-Variante: benannte Felder
|
||||||
|
Stein, // Keine Daten
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let haustiere = vec![
|
||||||
|
Tier::Hund("Bello".into()),
|
||||||
|
Tier::Fisch {
|
||||||
|
art: "Goldfisch".into(),
|
||||||
|
liter: 60,
|
||||||
|
},
|
||||||
|
Tier::Stein,
|
||||||
|
];
|
||||||
|
|
||||||
|
for tier in &haustiere {
|
||||||
|
match tier {
|
||||||
|
Tier::Hund(name) => println!("{name} will Gassi gehen"),
|
||||||
|
Tier::Fisch { art, liter } => println!("{art} braucht {liter}L Aquarium"),
|
||||||
|
Tier::Stein => println!("...braucht nichts."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Option<T> ersetzt null/nil. Der Compiler erzwingt, dass ihr den "nichts da"-Fall behandelt.
|
||||||
|
|
||||||
|
fn teile(a: f64, b: f64) -> Option<f64> {
|
||||||
|
if b == 0.0 {
|
||||||
|
None // Kein Ergebnis möglich
|
||||||
|
} else {
|
||||||
|
Some(a / b) // Ergebnis einpacken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let versuche = vec![(10.0, 3.0), (5.0, 0.0), (42.0, 7.0)];
|
||||||
|
|
||||||
|
for (a, b) in versuche {
|
||||||
|
// Ohne diesen match kompiliert der Code nicht ihr MÜSST den None-Fall behandeln.
|
||||||
|
match teile(a, b) {
|
||||||
|
Some(ergebnis) => println!("{a} / {b} = {ergebnis:.2}"),
|
||||||
|
None => println!("{a} / {b} = nicht möglich!"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
// Result<T, E> modelliert Erfolg ODER Fehler. Jeder Fehlertyp ist eine eigene Enum Variante.
|
||||||
|
|
||||||
|
#[derive(Debug)] //generiert automatisch eine Debug-Ausgabe
|
||||||
|
enum FehlerArt {
|
||||||
|
ZuKurz,
|
||||||
|
KeineZahl,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rückgabe ist entweder Ok(eine_zahl) oder Err(ein_fehler)
|
||||||
|
fn parse_alter(input: &str) -> Result<u32, FehlerArt> {
|
||||||
|
if input.len() < 1 {
|
||||||
|
return Err(FehlerArt::ZuKurz);
|
||||||
|
}
|
||||||
|
input.parse::<u32>().map_err(|_| FehlerArt::KeineZahl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let eingaben = vec!["25", "", "abc", "42"];
|
||||||
|
|
||||||
|
for e in eingaben {
|
||||||
|
match parse_alter(e) {
|
||||||
|
Ok(alter) => println!("\"{e}\" → Alter: {alter}"),
|
||||||
|
Err(FehlerArt::ZuKurz) => println!("\"{e}\" → Fehler: leere Eingabe"),
|
||||||
|
Err(FehlerArt::KeineZahl) => println!("\"{e}\" → Fehler: keine gültige Zahl"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Match Guards: ein `if` nach dem Pattern fügt eine zusätzliche Bedingung hinzu.
|
||||||
|
|
||||||
|
fn bewerte_note(punkte: u32) {
|
||||||
|
match punkte {
|
||||||
|
p if p >= 90 => println!("{p} Punkte → Sehr gut"),
|
||||||
|
p if p >= 75 => println!("{p} Punkte → Gut"),
|
||||||
|
p if p >= 50 => println!("{p} Punkte → Bestanden"),
|
||||||
|
p => println!("{p} Punkte → Durchgefallen"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
for p in [95, 80, 55, 30] {
|
||||||
|
bewerte_note(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
// Patterns können beliebig tief verschachtelt werden:
|
||||||
|
// Structs in Enums in Options – alles in einem match.
|
||||||
|
|
||||||
|
enum Inhalt {
|
||||||
|
Text(String),
|
||||||
|
Zahl(i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Paket {
|
||||||
|
absender: String,
|
||||||
|
inhalt: Option<Inhalt>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn oeffne(p: &Paket) {
|
||||||
|
match p {
|
||||||
|
// Option UND Enum gleichzeitig destrukturieren
|
||||||
|
Paket {
|
||||||
|
absender,
|
||||||
|
inhalt: Some(Inhalt::Text(t)),
|
||||||
|
} => {
|
||||||
|
println!("Von {absender}: Text \"{t}\"");
|
||||||
|
}
|
||||||
|
Paket {
|
||||||
|
absender,
|
||||||
|
inhalt: Some(Inhalt::Zahl(n)),
|
||||||
|
} => {
|
||||||
|
println!("Von {absender}: Zahl {n}");
|
||||||
|
}
|
||||||
|
// .. deckt restliche Felder ab (hier: absender)
|
||||||
|
Paket { inhalt: None, .. } => {
|
||||||
|
println!("Leeres Paket.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let pakete = vec![
|
||||||
|
Paket {
|
||||||
|
absender: "Alice".into(),
|
||||||
|
inhalt: Some(Inhalt::Text("Hallo".into())),
|
||||||
|
},
|
||||||
|
Paket {
|
||||||
|
absender: "Bob".into(),
|
||||||
|
inhalt: Some(Inhalt::Zahl(99)),
|
||||||
|
},
|
||||||
|
Paket {
|
||||||
|
absender: "Eve".into(),
|
||||||
|
inhalt: None,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for p in &pakete {
|
||||||
|
oeffne(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Exhaustiveness: der Compiler prüft, ob ALLE Varianten abgedeckt sind. Vergisst man eine → Compilerfehler.
|
||||||
|
|
||||||
|
enum Ampel {
|
||||||
|
Rot,
|
||||||
|
Gruen,
|
||||||
|
// Gelb, // ← einkommentieren und neu kompilieren!
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aktion(a: &Ampel) -> &str {
|
||||||
|
match a {
|
||||||
|
Ampel::Rot => "Stehen bleiben",
|
||||||
|
Ampel::Gruen => "Gehen",
|
||||||
|
// Ohne Arm für Gelb → Compilerfehler:
|
||||||
|
// "non-exhaustive patterns: `Gelb` not covered"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let ampeln = [Ampel::Rot, Ampel::Gruen];
|
||||||
|
|
||||||
|
for a in &eln {
|
||||||
|
println!("{}", aktion(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
// Tests werden mit "cargo test" ausgeführt
|
||||||
|
|
||||||
|
fn is_even(n: i32) -> bool {
|
||||||
|
n % 2 == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn double(n: i32) -> i32 {
|
||||||
|
n * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_one(n: i32) -> i32 {
|
||||||
|
n + 1
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("{} ist gerade: {}", 4, is_even(4));
|
||||||
|
println!("doppelt von 5: {}", double(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests liegen generell im selben file wie die Function selbst
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn even() {
|
||||||
|
assert!(is_even(4)); // bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn double_of_5() {
|
||||||
|
assert_eq!(double(5), 10); // Vergleich auf Gleichheit
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_one_changes_value() {
|
||||||
|
assert_ne!(add_one(5), 5); // Vergleich auf Ungleichheit
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue