Code review en Go: qué revisar y cómo dar retroalimentación
Code review (revisión de código) no es solo una formalidad, sino una de las herramientas más efectivas para mejorar la calidad del código, compartir conocimientos en el equipo y prevenir errores. En la comunidad de Go (Golang), el code review tiene una importancia especial, ya que el lenguaje fomenta la simplicidad, la legibilidad y el uso idiomático. En este artículo, analizaremos qué aspectos revisar al hacer code review de código Go y cómo dar retroalimentación para que sea útil, no ofensiva.
1. Principios generales del code review en Go
Antes de entrar en detalles técnicos, es importante recordar la cultura de la revisión. Tu objetivo es mejorar el código y ayudar a tu colega, no demostrar que tienes razón. Aquí hay algunas reglas de oro:
- Sé constructivo. En lugar de «esto está mal», escribe «aquí podría haber una fuga de gorutina, agreguemos un contexto».
- Pregunta, no afirmes. «¿Por qué elegiste
sync.Mutexen lugar de un canal?» es una buena pregunta. «Eres tonto, debiste usar un canal» es una mala. - No retrases la revisión. Intenta responder dentro de las 24 horas (o según lo acordado en el equipo).
- Enfócate en la lógica y la arquitectura. Las correcciones de estilo (espacios, sangrías) es mejor dejarlas a
gofmt.
2. ¿Qué revisar primero?: lista de verificación para Go
Aquí tienes una lista estructurada de aspectos a considerar al revisar código Go. La dividiremos en bloques lógicos.
2.1. Manejo de errores
En Go no hay excepciones, los errores son valores. Esta es una de las expresiones idiomáticas clave del lenguaje.
- Verifica todos los errores devueltos. Ignorar un error con
_solo es aceptable en casos muy raros (por ejemplo, al escribir enio.Discard). - No uses
panicpara errores comunes.panices para estados irrecuperables (por ejemplo, un error de inicialización del servidor). - Envuelve los errores. Usa
fmt.Errorf("algo salió mal: %w", err)para agregar contexto. Esto permite usarerrors.Is()yerrors.As().
// Mal: pérdida de contextoif err != nil { return err}
// Bien: envolvemos el errorif err != nil { return fmt.Errorf("no se pudo abrir el archivo %s: %w", filename, err)}2.2. Gorutinas y concurrencia
Go es famoso por su concurrencia ligera, pero también es fuente de muchos errores.
- Fugas de gorutinas. Asegúrate de que cada gorutina iniciada termine en algún momento. Usa contexto (
context.Context) para la cancelación. - Uso correcto de canales. Quien crea el canal, lo cierra. El cierre del canal es responsabilidad del emisor.
- Condición de carrera (data race). Evita escribir simultáneamente en una misma variable sin sincronización. Usa mutex (
sync.Mutex) o atómicos (sync/atomic).
// Ejemplo con contexto para cancelar una gorutinafunc process(ctx context.Context, dataCh chan int) { for { select { case <-ctx.Done(): log.Println("Finalizando trabajo") return case val, ok := <-dataCh: if !ok { return // canal cerrado } fmt.Println(val) } }}2.3. Expresiones idiomáticas y estilo en Go
Go es un lenguaje donde la legibilidad del código es lo más importante.
- Nombres de variables. Nombres cortos para ámbitos de visibilidad cortos.
ipara un bucle,rpara un reader. Para variables globales, nombres más largos. - Evita los «números mágicos». Usa constantes.