Code-Review in Go: Was prüfen und wie man Feedback gibt
\nCode-Review (Code-Überprüfung) ist nicht nur eine formale Prüfung vor dem Mergen eines Pull-Requests. Es ist ein mächtiges Werkzeug zur Verbesserung der Codequalität, zum Wissensaustausch im Team und zur Fehlervermeidung in frühen Phasen. Für angehende Go-Entwickler kann die Teilnahme an Reviews stressig wirken: Man hat Angst, Kritik zu erhalten oder umgekehrt einen kritischen Fehler zu übersehen. In diesem Artikel schauen wir uns an, worauf man beim Review von Go-Code achten sollte und wie man Feedback gibt, das hilfreich und nicht verletzend ist.
\n\nWarum ist Code-Review gerade in Go wichtig?
\nDie Sprache Go wurde mit Fokus auf Einfachheit, Lesbarkeit und Zuverlässigkeit entwickelt. Die Einfachheit der Syntax hebt jedoch nicht die Komplexität der Logik auf. Typische Probleme in Go-Projekten: Ignorieren von Fehlern, falscher Umgang mit Goroutinen, Ressourcenlecks. Ein gutes Code-Review hilft, diese und andere Probleme zu erkennen, bevor sie in die Produktion gelangen.
\n\nWas in Go-Code prüfen: Eine Checkliste für Anfänger
\nFür ein systematisches Review verwenden Sie eine Checkliste. Hier sind die wichtigsten Punkte, die Sie in jedem Pull-Request prüfen sollten.
\n\n1. Fehlerbehandlung (Error Handling)
\nIn Go sind Fehler Werte, sie dürfen nicht ignoriert werden. Prüfen Sie, dass jede Funktion, die error zurückgibt, diesen behandelt oder explizit nach oben reicht.
// Schlecht: Fehler ignorieren\nfile, _ := os.Open("config.yaml")\n\n// Gut: Fehler behandeln\nfile, err := os.Open("config.yaml")\nif err != nil {\n log.Fatalf("cannot open config: %v", err)\n}\ndefer file.Close()\nPrüfen Sie auch, dass Fehler mit fmt.Errorf("...: %w", err) umschlossen werden, um Kontext zu übergeben, und nicht nur geloggt und geschluckt werden.
2. Benennung und Lesbarkeit
\nIn Go sind kurze Namen für Variablen üblich (z.B. r für Reader, w für Writer) und lange Namen für exportierte Funktionen. Prüfen Sie, dass:
- \n
- Exportierte Funktionen, Typen und Variablen Kommentare haben (beginnend mit dem Namen der Entität). \n
- Variablennamen ihren Zweck widerspiegeln (nicht
a,b,tmp). \n - Keine unnötigen Abkürzungen verwendet werden (
calcbesser durchcalculateersetzen). \n
3. Arbeit mit Goroutinen und Nebenläufigkeit
\nGoroutinen sind ein mächtiges, aber gefährliches Werkzeug. Prüfen Sie:
\n- \n
- Gibt es einen Synchronisationsmechanismus (Channels, Mutexe) für gemeinsame Daten. \n
- Werden keine "leckenden" Goroutinen (Goroutine Leak) erstellt. Verwenden Sie Kontext (
context.Context) zum Abbrechen. \n - Wird eine Goroutine nicht für immer blockiert (Deadlock). \n
// Beispiel für sicheres Arbeiten mit einer Goroutine\nfunc worker(ctx context.Context, jobs <-chan int, results chan<- int) {\n for {\n select {\n case job, ok := <-jobs:\n if !ok {\n return\n }\n results <- job * 2\n case <-ctx.Done():\n return\n }\n }\n}\n\n4. Ressourcenverwaltung (defer)
\nPrüfen Sie, dass alle geöffneten Dateien, Netzwerkverbindungen, DB-Transaktionen über defer geschlossen werden. Dies sollte direkt nach dem erfolgreichen Öffnen der Ressource erfolgen.
// Richtig: sofort schließen\nconn, err := net.Dial("tcp", "example.com:80")\nif err != nil {\n return err\n}\ndefer conn.Close()\n\n5. Testen
\nAnfänger vergessen oft Tests. Stellen Sie sicher, dass für die neue Logik Unit-Tests geschrieben wurden. Prüfen Sie:
\n- \n
- Die Tests decken nicht nur den Happy Path ab, sondern auch Randfälle. \n
- Wird
t.Runfür Subtests verwendet. \n - Gibt es Tests, die ohne Mocks von externen Ressourcen (DB, Netzwerk) abhängen. \n
Wie man Feedback gibt: 5 Regeln für Anfänger
\nDer technische Teil ist die eine Hälfte. Die andere Hälfte ist die Kommunikationsfähigkeit. Hier sind die