Kurz: // Shadowing: neue Variable mit demselben Namen let x = 5; let x = x * 2; let x = format!(“{x} Stück”);
Teil des Kurses Rust
fn main() {
let name = "Mia"; // unveränderlich (Standard)
let mut punkte = 0; // veränderlich
punkte += 10;
let alter: u32 = 17; // Typ ausdrücklich
const MAX: u32 = 100; // Konstante: immer Typ nötig
// Shadowing: neue Variable mit demselben Namen
let x = 5;
let x = x * 2;
let x = format!("{x} Stück");
println!("{name} hat {punkte} Punkte, ist {alter}, Max {MAX}");
println!("{x}");
println!("{} + {} = {}", 3, 4, 3 + 4);
println!("{:>6}|{:<6}|{:^6}|{:06.2}|{:#x}|{:#b}", "ab", "cd", "ef", 3.14159, 255, 5);
println!("{0} {1} {0} {n}", "a", "b", n = 5);
println!("{:?} {:?}", (1, "zwei"), vec![1, 2, 3]);
}Ausgabe:
Mia hat 10 Punkte, ist 17, Max 100
10 Stück
3 + 4 = 7
ab|cd | ef |003.14|0xff|0b101
a b a 5
(1, "zwei") [1, 2, 3]letlegt eine Variable an, standardmäßig unveränderlichlet mutmacht sie veränderlich- Shadowing (
let x = ...erneut) legt eine neue Variable an, auch mit anderem Typ {}gibt mitDisplayaus,{:?}mitDebug(für Entwickler),{name}setzt Variablen direkt ein
Datentypen
| Typ | Beschreibung |
|---|---|
i8 i16 i32 i64 i128 isize | vorzeichenbehaftete ganze Zahlen (i32 Standard) |
u8 u16 u32 u64 u128 usize | vorzeichenlose; usize für Indizes und Größen |
f32, f64 | Kommazahlen (f64 Standard) |
bool | true / false |
char | ein Unicode-Zeichen (4 Byte), in '...' |
&str | Textsicht (String-Slice), "..." |
String | wachsender, besitzender Text |
() | Einheitstyp (“nichts”) |
(A, B) | Tupel |
[T; N] | Array fester Länge |
Vec<T> | wachsende Liste |
fn main() {
let a: i32 = -42;
let b: u8 = 255;
let c = 3.14; // f64
let d = 'ß';
let t = (500, 6.4, "x"); // Tupel
let (x, y, z) = t; // Destructuring
let feld = [1, 2, 3, 4, 5];
let nullen = [0; 4];
println!("{a} {b} {c} {d} {} {} {} {}", t.0, x + 1, y, z);
println!("{} {} {:?} {:?}", feld[0], feld.len(), nullen, &feld[1..3]);
println!("{} {} {}", i32::MAX, u8::MAX, f64::EPSILON > 0.0);
println!("{}", 7 / 2); // 3: Ganzzahldivision
println!("{}", 7.0 / 2.0);
println!("{}", -7 % 3);
}Ausgabe:
-42 255 3.14 ß 500 501 6.4 x
1 5 [0, 0, 0, 0] [2, 3]
2147483647 255 true
3
3.5
-1Umwandlungen
Rust wandelt Zahlentypen nie automatisch um. Du schreibst as oder die From/TryFrom-Methoden:
fn main() {
let i: i32 = 300;
let f = i as f64 / 7.0;
let klein = i as u8; // schneidet ab: 300 -> 44 (Vorsicht!)
let sicher = u8::try_from(i); // Result: Fehler bei Überlauf
let gross: i64 = i.into(); // verlustfreie Umwandlung
println!("{f:.2} {klein} {:?} {gross}", sicher.is_err());
let n: i32 = "42".parse().unwrap();
let kaputt = "abc".parse::<i32>();
println!("{} {:?}", n + 1, kaputt.is_err());
println!("{}", 255u8.checked_add(1).is_none()); // Überlauf prüfen
println!("{} {}", 250u8.wrapping_add(10), 250u8.saturating_add(10));
}Ausgabe:
42.86 44 true 300
43 true
true
4 255Im Debug-Modus bricht ein Ganzzahl-Überlauf (255u8 + 1) mit einer Panic ab; im Release-Modus läuft er um. Nutze checked_*, wrapping_* oder saturating_*, wenn du das Verhalten festlegen willst.
Strings: String und &str
fn main() {
let literal: &str = "Hallo"; // fest im Programm, unveränderlich
let mut s = String::from("Hallo"); // wächst
s.push_str(", Welt");
s.push('!');
println!("{s} {} {}", s.len(), s.to_uppercase());
println!("{} {} {:?}", s.contains("Welt"), s.replace("Hallo", "Servus"), s.find("Welt"));
println!("{}", &s[0..5]); // Teilstring (Bytes!)
for (i, c) in "aß".chars().enumerate() { print!("{i}:{c} "); }
println!();
println!("{} {}", "ß".len(), "ß".chars().count()); // Bytes vs Zeichen
let teile: Vec<&str> = "a,b,c".split(',').collect();
println!("{teile:?} {}", teile.join("+"));
let zusammen = format!("{literal}-{s}");
println!("{zusammen} {}", literal.trim().is_empty());
}Ausgabe:
Hallo, Welt! 12 HALLO, WELT!
true Servus, Welt! Some(7)
Hallo
0:a 1:ß
2 1
["a", "b", "c"] a+b+c
Hallo-Hallo, Welt! falseString besitzt seinen Text auf dem Heap, &str ist eine Sicht darauf. Funktionen nehmen meist &str als Parameter.
Merke
let(unveränderlich) undlet mut; Shadowing legt neue Variablen an- Typen:
i32,u8,f64,bool,char,&str,String, Tupel, Arrays,Vec<T> - Keine automatische Umwandlung zwischen Zahlentypen:
as,into,try_from {}Display,{:?}Debug,{name}Inline-Variablenchecked_*/wrapping_*/saturating_*steuern Überlaufverhalten
Übungsaufgabe
Wandle eine Temperatur in Celsius (f64) in Fahrenheit um und gib sie mit einer Nachkommastelle aus.
Quiz zur Selbstkontrolle
Sind Variablen in Rust standardmäßig veränderlich?
- Nein, mit mut werden sie veränderlich (richtig)
- Ja
- Nur Zahlen
- Nur Strings
Was ist Shadowing?
- Eine neue Variable mit demselben Namen anlegen (richtig)
- Eine Variable löschen
- Eine Variable verstecken vor dem Compiler
- Eine Kopie im Hintergrund
Was ist der Unterschied zwischen String und &str?
- String besitzt seinen Text, &str ist eine Sicht darauf (richtig)
- Kein Unterschied
- &str ist veränderlich
- String ist für Zahlen
Weiter im Kurs
Zurück: Was ist Rust?
Weiter: Bedingungen, Schleifen und match
Alle Kapitel: Rust im Überblick