💡 1. Immutability by Default: let vs. let mut
In Rust sind alle Variablen standardmäßig unveränderlich (immutable). Das verhindert versehentliche Zustandsänderungen in komplexen Systemen und nebenläufigen Programmen bereits zur Compile-Zeit:
fn main() {
// 1. Unveränderliche Variable (Immutable)
let max_connections = 100;
// max_connections = 200; // ❌ COMPILE-FEHLER: cannot assign twice to immutable variable
// 2. Veränderbare Variable mit dem Schlüsselwort 'mut'
let mut current_load = 42;
current_load = 43; // ✅ Gültig!
// 3. Konstanten: Immer unveränderlich, Typ-Annotation ist Pflicht!
const MAX_RETRIES: u32 = 5;
println!("Max: {}, Current: {}, Retries: {}", max_connections, current_load, MAX_RETRIES);
}
Ein normales let ist wie ein in Stein graviertes Türschild: Einmal angebracht, kann es niemand unbemerkt überschreiben. Nur wenn du explizit let mut wählst, stellst du ein Whiteboard auf, auf dem Werte abgewischt und neu geschrieben werden dürfen.
📐 2. Das statische Typensystem von Rust
Rust ist statisch typisiert, verfügt jedoch über eine hochpräzise Type Inference (Typableitung). Der Compiler weiß meist selbst, welcher Typ gemeint ist.
| Kategorie | Rust Typen | Beispiel | Besonderheiten |
|---|---|---|---|
| Ganzzahlen (Signed) | i8, i16, i32, i64, i128, isize |
-42_i32 |
Standard: i32. _ als Tausendertrennzeichen erlaubt. |
| Ganzzahlen (Unsigned) | u8, u16, u32, u64, u128, usize |
1024_u32 |
usize entspricht der Pointer-Größe (für Array-Indizes). |
| Fließkommazahlen | f32, f64 |
3.1415_f64 |
Standard: f64 (doppelte IEEE-754 Präzision). |
| Booleans & Chars | bool, char |
true, '🦀' |
char ist 4 Bytes groß (echtes Unicode Scalar Value). |
| Tupel (Tuples) | (T1, T2, ...) |
("rust", 2024, true) |
Feste Länge, heterogene Typen. Zugriff: tup.0, tup.1. |
| Arrays | [T; N] |
[1, 2, 3, 4] |
Feste Länge zur Compile-Zeit, homogener Typ, auf dem Stack! |
Explizite Typkonvertierung mit as
Rust führt niemals automatische Typ-Casts durch. Jede Konvertierung zwischen numerischen Typen muss mit dem as Keyword explizit deklariert werden:
let total_bytes: u64 = 1048576;
let chunk_size: u32 = 1024;
// let chunks = total_bytes / chunk_size; // ❌ Fehler: Typen u64 und u32 inkompatibel
let chunks = total_bytes / (chunk_size as u64); // ✅ Korrekt
👥 3. Shadowing: Der saubere Namens-Neustart
In Rust kannst du eine Variable mit let erneut deklarieren. Dies nennt man Shadowing. Dabei wird die alte Variable verdeckt und du kannst sogar den Datentyp ändern, ohne einen neuen Variablennamen erfinden zu müssen:
let input = " 42 "; // Typ: &str
let input = input.trim(); // Typ: &str ("42")
let input: i32 = input.parse().unwrap(); // Typ: i32 (42)
println!("Geparster Integer: {}", input);
let mutBei let mut behält die Variable denselben Datentyp und Speicherort. Beim Shadowing entsteht eine komplett neue Variable mit eigenem Typ und Scope. Die alte Variable bleibt unveränderlich geschützt!