Code-Review auf Go: Was man prüfen sollte, damit der Code nicht explodiert
\n\nCode-Review ist nicht nur ein Häkchen in Jira oder ein Grund, sich mit einem Kollegen in den Kommentaren eines Pull-Requests zu streiten. Es ist wohl der ehrlichste Weg, sich nicht selbst ins Bein zu schießen, wenn es in die Produktion geht. Und wenn es um Go geht – eine Sprache, die für ihre Einfachheit geliebt und dafür gehasst wird, „wo sind hier die Generics?“ (Spoiler: Sie sind bereits da) – wird das Review zur Kunst. In diesem Artikel analysieren wir, worauf man bei einem Code-Review auf Go genau achten sollte, damit Ihr Code nicht nur funktioniert, sondern auch eine Freude fürs Auge ist. Los geht's!
\n\n1. Fehlerbehandlung: Nicht ignorieren, keine Angst haben
\n\nIn Go gibt es keine Ausnahmen. Hier ist alles ehrlich: Wenn eine Funktion fehlschlagen kann, gibt sie error zurück. Das häufigste Problem bei Anfängern ist das Ignorieren von Fehlern durch einen Unterstrich. Denken Sie daran: „Never ignore an error“ – das ist nicht nur ein Mantra, es ist ein Gesetz.
Was im Code prüfen:
\n- \n
- Prüfung auf err != nil – sie muss überall dort sein, wo eine Funktion einen Fehler zurückgibt. Selbst wenn Sie sicher sind, dass „hier kein Fehler auftreten wird“. \n
- Loggen oder Weiterleiten – der Fehler muss entweder mit Kontext geloggt oder nach oben zurückgegeben werden. Ihn zu unterdrücken ist ein No-Go. \n
- Vergleich mit Sentinel-Fehlern – verwenden Sie
errors.Is()underrors.As(), nicht den direkten Vergleich mit==. \n
// Schlecht: Fehler ignorieren\nfile, _ := os.Open("config.yaml")\n\n// Gut: Prüfen und loggen\nfile, err := os.Open("config.yaml")\nif err != nil {\n log.Printf("Konnte Konfiguration nicht öffnen: %v", err)\n return err\n}\ndefer file.Close()\n\n\n2. Goroutinen und Nebenläufigkeit: Ordnung im Chaos
\n\nGoroutinen sind die Superkraft von Go. Aber mit großer Kraft kommt große Verantwortung. Beim Review sehen wir oft Goroutinen-Leaks, Datenrennen und Blockaden. Ein Code-Review in Go ohne Prüfung der Nebenläufigkeit ist wie Sportwagenfahren ohne Sicherheitsgurt.
\n\nCheckliste für Goroutinen:
\n- \n
- Starten von Goroutinen – kontrollieren Sie immer die Lebensdauer. Verwenden Sie
sync.WaitGroupoder Kontexte. \n - Datenrennen – prüfen Sie, ob der Zugriff auf gemeinsame Daten durch einen Mutex oder einen Kanal geschützt ist. Führen Sie
go test -raceaus. \n - Panik in einer Goroutine – wenn eine Goroutine in Panik gerät, stürzt das gesamte Programm ab. Verwenden Sie in Production-Code unbedingt
recover. \n
// Schlecht: Goroutine ohne Kontrolle\ngo func() {\n // Kann abstürzen und den gesamten Prozess killen\n doWork()\n}()\n\n// Gut: Mit WaitGroup und recover\nvar wg sync.WaitGroup\nwg.Add(1)\ngo func() {\n defer wg.Done()\n defer func() {\n if r := recover(); r != nil {\n log.Printf("Goroutine abgestürzt: %v", r)\n }\n }()\n doWork()\n}()\nwg.Wait()\n\n\n3. Schnittstellen: Klein und zur Sache
\n\nIn Go sind Schnittstellen Verträge. Aber im Gegensatz zu Java müssen sie nicht riesig sein. In der Go-Community gilt das Prinzip: „Je kleiner die Schnittstelle, desto besser“. Eine Methode – ideal. Zwei – in Ordnung. Drei – bereits verdächtig.
\n\nWorauf achten:
\n- \n
- Größe der Schnittstelle – wenn sie mehr als 3-4 Methoden hat, denken Sie über eine Aufteilung nach. \n
- Akzeptieren Sie Schnittstellen, geben Sie Strukturen zurück – klassische Go-Weisheit. Sie macht den Code flexibel und testbar. \n
- Definieren Sie Schnittstellen nicht im Voraus – lassen Sie sie vom Konsumenten erstellen, nicht vom Produzenten. \n
// Schlecht: Riesige Schnittstelle\ntype Storage interface {\n Save(data []byte) error\n Load(id string) ([]byte, error)\n Delete(id string) error\n List() ([]string, error)\n Connect() error\n Close() error\n}\n\n// Gut: Kleine Schnittstellen\ntype Saver interface {\n Save(data []byte) error\n}\ntype Loader interface {\n Load(id string) ([]byte, error)\n}\n
Blogs
Buchempfehlungen
Lesen Sie auch
Entwurfsmuster in TypeScript: Beispiele und Implementierung
Dokumentation von Go-Projekten: Fortgeschrittene Techniken und Werkzeuge
Reflexion und Introspektion in C#: Wie man in seinen eigenen Code hineinschaut
Die 10 besten Go-Frameworks für die Webentwicklung im Jahr 2025
# oder javascript:void(0): Was für JS-Links wählen?