Code Review in Rust: Was prüfen und wie man Feedback gibt – Ein Leitfaden für Anfänger
Code Review (Code-Überprüfung) ist der Prozess der Überprüfung fremden Codes, bevor er in den Hauptzweig des Projekts eingefügt wird. Für die Sprache Rust, die für ihr strenges Typsystem, ihre Speichersicherheit und ihr einzigartiges Ownership-Modell bekannt ist, gewinnt das Code Review eine besondere Bedeutung. Anfänger stoßen oft auf Schwierigkeiten: Wie erkennt man, ob Code "rustisch" geschrieben ist? Wie verletzt man den Autor nicht, wenn man auf Fehler hinweist? In diesem Artikel werden wir die wichtigsten Aspekte des Reviews für Rust durchgehen, Beispiele zeigen und praktische Ratschläge geben.
1. Grundprinzipien des Code Reviews in Rust
Bevor wir uns in technische Details vertiefen, ist es wichtig, die Philosophie des Reviews zu verstehen. Ihr Ziel ist es nicht, alle Mängel zu finden, sondern einem Kollegen (oder sich selbst) zu helfen, qualitativ hochwertigen, wartbaren Code zu schreiben. In Rust ist dies aufgrund der strengen Regeln des Borrow Checkers und des Ownership-Systems besonders wichtig.
Hier ist, worauf Sie zuerst achten sollten:
- Korrektheit der Speicherverwaltung – auch wenn der Code kompiliert, sind logische Fehler möglich.
- Einhaltung der Rust-Idiome – Verwendung von
Option,Result, Traits anstelle von Vererbung. - Lesbarkeit und Dokumentation – Kommentare, Benennung von Variablen, Struktur der Module.
- Leistung – Vermeidung unnötiger Klone und Allokationen.
Für angehende Reviewer ist es wichtig, sich daran zu erinnern: Sie müssen nicht alles wissen. Wenn etwas unklar ist – fragen Sie nach. Das ist normal.
2. Was im Rust-Code prüfen: Eine Checkliste für Anfänger
Lassen Sie uns konkrete Punkte durchgehen, auf die Sie beim Review von Rust-Code achten sollten.
2.1. Umgang mit Ownership und Borrowing
Rust ist die einzige populäre Sprache, in der die Konzepte ownership, borrowing und lifetimes in den Compiler integriert sind. Das Review kann jedoch Probleme aufdecken, die der Compiler nicht sieht:
- Übermäßiges Klonen. Wenn der Autor überall
.clone()verwendet, wo eine Referenz ausreicht – das ist eine schlechte Praxis. Beispiel:
// Schlecht: Klonen ohne Notwendigkeitfn process(data: Vec<i32>) { let cloned = data.clone(); // ... verwenden cloned}
// Gut: Referenz übergebenfn process(data: &Vec<i32>) { // ... verwenden &data}- Falsche Verwendung von Lifetimes. Wenn im Code explizite
'a-Annotationen vorkommen, stellen Sie sicher, dass sie wirklich benötigt werden. Oft können sie dank der Elision (lifetime elision) weggelassen werden. - Speicherlecks durch
RcoderArc. Prüfen Sie, ob es zirkuläre Referenzen gibt (fürRcverwenden SieWeak).
2.2. Fehlerbehandlung
Rust fördert die explizite Fehlerbehandlung durch Result und Option. Achten Sie beim Review auf:
- Unbenutzte
Result. Wenn eine Funktion einResultzurückgibt, das Ergebnis aber ignoriert wird – das ist ein potenzielles Problem. Verwenden Sielet _ = ...oder die Methode.ok(). - Missbrauch von
unwrap(). In Production-Code solltenunwrap()undexpect()gerechtfertigt sein. Besser ist die Verarbeitung durchmatchoder den?-Operator.
// Schlecht: Kann eine Panik auslösenlet value = some_result.unwrap();
// Gut: Fehlerbehandlunglet value = match some_result { Ok(v) => v, Err(e) => { eprintln!("Fehler: {}", e); return; }};2.3. Verwendung von Traits und generischer Programmierung
Rust unterstützt keine Vererbung – stattdessen werden Traits verwendet