Code Review in Go: Was prüfen und wie man Feedback gibt
Code Review ist nicht nur eine Formalität, sondern eine entscheidende Entwicklungsphase. Besonders in Go, wo Einfachheit und Lesbarkeit des Codes in der Sprachphilosophie verankert sind. Für Anfänger kann dies einschüchternd wirken: Wie kann man fremden Code kritisieren, wenn man selbst noch unsicher ist? Tatsächlich ist Code Review der beste Weg, um zu lernen. In diesem Artikel analysieren wir, worauf man bei der Überprüfung von Go-Code achten sollte und wie man Feedback gibt, das nützlich und nicht verletzend ist.
1. Grundprinzipien: Worauf man zuerst achten sollte
Bevor wir ins Detail gehen, merken Sie sich die Hauptregel: Das Review betrifft den Code, nicht die Person. Ihr Ziel ist es, potenzielle Probleme zu finden und die Produktqualität zu verbessern, nicht zu beweisen, dass Sie schlauer sind. Beginnen Sie mit einfachen Dingen:
- Logische Fehler: Werden Randfälle korrekt behandelt? Was passiert zum Beispiel, wenn ein Slice leer ist?
- Potenzielle Paniken: Haben Sie
nilvergessen? Überprüfen Sie, dass Sie keine Methoden auf einem Nullzeiger aufrufen. - Unbenutzter Code: In Go führt dies zu einem Kompilierungsfehler, aber manchmal bleiben tote Variablen oder Importe übrig.
Beispiel für einen typischen Anfängerfehler:
func getFirstElement(s []int) int { return s[0] // Panik, wenn das Slice leer ist!}Was im Review vorgeschlagen werden sollte: Eine Längenprüfung des Slices hinzufügen und einen Fehler zurückgeben.
func getFirstElement(s []int) (int, error) { if len(s) == 0 { return 0, fmt.Errorf("slice is empty") } return s[0], nil}2. Go-Idiome: Wie man „Go-like“ schreibt
Go ist weder Java noch Python. Es hat seinen eigenen Stil, den man respektieren sollte. Achten Sie beim Review auf folgende Punkte:
- Benennung: In Go sind kurze Namen üblich (z.B.
rfür Reader,wfür Writer). Nennen Sie eine Variable nichtmyReader– einfachr. - Fehlerbehandlung: Ignorieren Sie keine Fehler! Wenn eine Funktion
errorzurückgibt, muss sie überprüft werden. Ausnahme sindfmt.Printlnund ähnliche, aber auch diese sollten besser geloggt werden. - Schnittstellen: Sie sollten klein sein. Eine Methode ist gut, zwei sind schon viel. Erstellen Sie keine Schnittstellen „für die Zukunft“.
Beispiel für „nicht-Go-like“ Code:
func ProcessData(data []string) (bool, error) { var result bool for _, item := range data { if item == "error" { result = false return result, errors.New("found error") } } result = true return result, nil}Hier wird result nicht benötigt – man kann direkt true oder false zurückgeben. Außerdem sollte fmt.Errorf zur Formatierung verwendet werden.
func ProcessData(data []string) (bool, error) { for _, item := range data { if item == "error" { return false, fmt.Errorf("found error in item: %s", item) } } return true, nil}3. Leistung und Speicher: Worauf zu achten ist
Obwohl Go recht schnell ist, kann schlechter Code alles ruinieren. Überprüfen Sie beim Review:
- Vermeiden Sie unnötige Allokationen: Wenn Sie die Größe eines Slices kennen, verwenden Sie
makemit Angabe der Kapazität. - Kopieren von Strukturen: Große Strukturen sollten besser per Zeiger übergeben werden, um sie nicht jedes Mal zu kopieren.
- Goroutinen: Überprüfen Sie, ob Sie vergessen haben, einen Kanal zu schließen oder auf die Beendigung einer Goroutine zu warten (verwenden Sie
sync.WaitGroup).
Beispiel für schlechte Arbeit mit einem Slice:
func appendItems(items []int) []int { var result []int for _, v := range items {