Code Review auf Rust: Worauf man achten muss, damit der Code nicht auseinanderfällt

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

Warum Code Review auf Rust mehr ist als nur Klammern zu prüfen



Rust ist eine Sprache, die sichere Speicherverwaltung und hohe Leistung verspricht. Aber selbst der strengste Compiler schützt nicht vor logischen Fehlern, unidiomatischem Code oder ungerechtfertigter Verwendung von unsafe. Code Review auf Rust ist eine Kunst. Sie schauen nicht nur, ob die geschweiften Klammern geschlossen sind. Sie prüfen, wie der Entwickler die Einschränkungen des Borrow Checkers umgangen (oder nicht umgangen) hat, wie effizient er Iteratoren einsetzt und ob er versucht, das System mit rohen Zeigern zu „überlisten".



In diesem Artikel erkläre ich, auf welche Aspekte Sie bei einem Code Review in Rust achten sollten. Ohne überflüssige Theorie – nur praktische Tipps, Beispiele und eine Checkliste, die Sie an die Wand hängen (oder in den Lesezeichen speichern) können. Los geht's!



1. Ownership, Borrowing und Lebenszeiten: Die Hauptschmerzquelle



Das Erste, was Sie prüfen müssen, ist, ob das Ownership-System korrekt funktioniert. Auch wenn der Code kompiliert, heißt das nicht, dass er korrekt ist. Typische Probleme:



  • Übermäßiges Klonen. Wenn eine Referenz ausgereicht hätte, kopiert der Entwickler die Daten. Das tötet die Leistung.
  • Ausleihen von mutable und immutable. Wenn es im selben Gültigkeitsbereich gleichzeitig &mut T und &T gibt – das führt zu einem Fehler. Manchmal kann man den Code jedoch umordnen, um dies zu vermeiden.
  • Falsche Lebenszeiten (Lifetimes). Besonders in komplexen Strukturen mit mehreren Referenzen.


Beispiel: Schlechter Code

fn process(data: &Vec<i32>) -> i32 {    let mut sum = 0;    for &x in data.iter() {        sum += x;    }    // Alles okay, aber warum &Vec übergeben, wenn &[i32] reicht?    sum}


Guter Code

fn process(data: &[i32]) -> i32 {    data.iter().sum()}


Was beim Review prüfen: Wird &Vec, &String oder &HashMap übergeben, wo ein Slice ausreicht? Werden clone() unnötig verwendet? Sind die Lebenszeit-Annotationen korrekt gesetzt?



2. Unsafe: Die rote Zone



unsafe-Blöcke sind wie eine offene Luke im sicheren Rust. Sie müssen gerechtfertigt, minimal und sorgfältig dokumentiert sein. Achten Sie beim Code Review auf:



  • Warum wird unsafe verwendet? Oft kommt man mit sicheren Abstraktionen aus.
  • Korrektheit roher Zeiger. Wird ein Nullzeiger dereferenziert? Hängt eine Referenz nach der Speicherfreigabe?
  • Invarianten. Code mit unsafe sollte explizit beschreiben, welche Invarianten er aufrechterhält.


Beispiel: Gefährliches unsafe

unsafe fn dangerous() {    let ptr = 0x12345 as *mut i32;    *ptr = 42; // Was ist, wenn an dieser Adresse nichts ist?}


Solcher Code sollte das Review nicht bestehen. Auch wenn „es funktioniert" – das ist kein Argument.



Gutes unsafe

unsafe fn init_buffer(buf: &mut [u8]) {    // Wir sind sicher, dass buf auf gültigen Speicher zeigt,    // da die aufrufende Seite dies garantiert.    std::ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len());}


Was prüfen: Gibt es einen Kommentar mit Begründung für jedes unsafe? Gibt es Tests, die Grenzfälle prüfen? Werden die Sicherheitsgarantien verletzt?



3. Closures und funktionaler Stil



Rust fördert einen funktionalen Ansatz: Iteratoren, Closures, map, filter, fold. Dies kann jedoch zu übermäßiger Komplexität führen. Achten Sie beim Review auf:



  • Werden Closures übermäßig genutzt? Wenn eine Closure viele Variablen einfängt, sollte die Logik vielleicht in eine separate Funktion ausgelagert werden.

Blogs

Buchempfehlungen