Top Fehler von Rust-Anfängern: Wie man sie vermeidet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung

Rust ist eine leistungsstarke Systemprogrammiersprache, die aufgrund ihrer Sicherheit und Leistung an Popularität gewinnt. Allerdings verwirrt ihr System der Ownership und des Borrowings oft Anfänger. In diesem Artikel analysieren wir die Top-Fehler von Rust-Anfängern, damit Sie diese vermeiden und sich schneller mit der Sprache vertraut machen können. Wir betrachten typische Probleme mit Borrowing, Lifetimes, Strings und Speicherverwaltung.



1. Ignorieren der Borrow-Checker-Regeln

Der häufigste Fehler ist der Versuch, gleichzeitig eine veränderliche und eine unveränderliche Referenz auf dieselben Daten zu haben. Rust verbietet dies strikt zur Kompilierzeit.



Problem: Mehrfache Referenzen

fn main() {    let mut data = vec![1, 2, 3];    let ref1 = &data; // unveränderliche Referenz    let ref2 = &mut data; // veränderliche Referenz — FEHLER!    println!("{} {}", ref1[0], ref2[0]);}

Der Compiler gibt einen Fehler aus: cannot borrow `data` as mutable because it is also borrowed as immutable.



Lösung: Korrekter Gültigkeitsbereich

fn main() {    let mut data = vec![1, 2, 3];    {        let ref1 = &data; // unveränderliche Referenz        println!("{}", ref1[0]);    } // ref1 verlässt den Gültigkeitsbereich    let ref2 = &mut data; // jetzt möglich    ref2[0] = 10;    println!("{}", ref2[0]);}

Achten Sie stets auf die Lebensdauer von Referenzen. Wenn Sie sowohl mit einer veränderlichen als auch mit einer unveränderlichen Referenz arbeiten müssen, trennen Sie diese in verschiedene Blöcke.



2. Falscher Umgang mit Strings: String vs &str

Anfänger verwechseln oft String (besitzender Typ, veränderlich) und &str (Referenz auf einen String-Slice). Dies führt zu Fehlern bei der Übergabe von Strings an Funktionen.



Problem: Erwartung von Ownership statt Referenz

fn print_length(s: String) {    println!("Länge: {}", s.len());}

fn main() { let name = "Alice".to_string(); print_length(name); println!("Name: {}", name); // FEHLER! name wurde verschoben}


Lösung: Verwenden Sie &str für Parameter

fn print_length(s: &str) {    println!("Länge: {}", s.len());}

fn main() { let name = "Alice".to_string(); print_length(&name); // Referenz übergeben println!("Name: {}", name); // funktioniert jetzt}

Faustregel: Wenn eine Funktion keinen Besitz übernehmen soll, verwenden Sie &str. Dies macht den Code flexibel – Sie können sowohl &String als auch String-Literale "text" übergeben.



3. Fehler mit Lifetimes

Wenn eine Funktion eine Referenz zurückgibt, verlangt Rust die Angabe, wie lange diese Referenz leben wird. Anfänger vergessen oft die Lifetime-Annotationen.



Problem: Implizite Lifetimes

fn longest(x: &str, y: &str) -> &str { // FEHLER: missing lifetime specifier    if x.len() > y.len() { x } else { y }}


Lösung: Gemeinsame Lifetime hinzufügen

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {    if x.len() > y.len() { x } else { y }}

fn main() { let s1 = String::from("kurz"); let s2 = "langer String"; let result = longest(&s1, &s2); println!("Längster: {}", result);}

Die Annotation 'a teilt dem Compiler mit, dass die zurückgegebene Referenz nicht länger lebt als der kürzeste der Eingabeparameter. Dies garantiert Speichersicherheit.



4. Ignorieren von Option und Result

Rust hat kein null. Stattdessen werden Option<T> für mögliches Fehlen eines Wertes und Result<T, E> für die Fehlerbehandlung verwendet. Anfänger versuchen oft, Option ohne Prüfung zu dereferenzieren.



Problem: Panic bei unwrap

fn find_user(id: u32) -> Option<String> {    if id == 1 {        Some("Anna".to_string())                

Blogs

Buchempfehlungen