Buenas Prácticas de Flujo de Control
Hábitos de control de flujo legibles y cuándo refactorizar la lógica anidada.
Busca en todas las páginas de la documentación
Hábitos de control de flujo legibles y cuándo refactorizar la lógica anidada.
Estas reglas mantienen el código Go plano, predecible y seguro bajo concurrencia, desde la disciplina de if err != nil hasta los límites de pánico en servidores.
if anidadas o manejadores con muchos bucles lleguen a un PR.go vet, staticcheck y golangci-lint para detectar automáticamente flujos de control sospechosos.if estilo inicialización. if err := f(); err != nil { return err } supera las rutas de éxito anidadas.switch para la discriminación de múltiples valores sobre una expresión. Las largas cadenas else if sobre la misma variable indican un switch.fallthrough a menos que puedas nombrar la razón en un comentario. Los cuerpos de casos compartidos deben llamar a una función auxiliar en su lugar.panic para fallos esperados de solicitud o I/O. Retorna error y deja que los llamadores mapeen a estados HTTP/gRPC.rangefor range para slices, mapas, canales y cadenas. Usa bucles de índice cuando necesites vecinos o iteración inversa.s[i] = x actualiza la colección; el valor del rango es una copia.defer en rutas de código antiguas. Las copias defensivas documentan la intención incluso en bibliotecas Go 1.22+.for range en canales se bloquea si nadie cierra.break, continue, etiquetas y deferbreak label al salir de bucles de búsqueda anidados. Reemplaza pirámides booleanas de found con una etiqueta o return auxiliar.break para salir de bucles for { select }. Un break simple solo sale del select, no del bucle.defer inmediatamente después de la adquisición exitosa de recursos. Los lectores emparejan Open/Lock con defer Close/Unlock visualmente.defer dentro de bucles ajustados sin una función anidada. Las pilas de defer crecen hasta que la función externa retorna.chi Recoverer, gin Recovery, echo Recover, o defer recover escrito a mano.return después de escribir respuestas. Nunca llames a next después de haber completado la respuesta.r.Context() a I/O downstream. El middleware de tiempo de espera solo funciona cuando los manejadores respetan la cancelación.defer r.Body.Close() (o equivalente) por solicitud. Los cuerpos filtrados agotan las conexiones bajo carga.Raramente más de dos niveles en el código de aplicación.
Extrae funciones o usa cláusulas de guarda cuando sea más profundo.
Cuando un doble bucle ajustado justificaría una llamada adicional y la etiqueta nombra claramente el objetivo de salida.
Si la lógica crece más allá de eso, extrae.
Sí, para bloqueos a nivel de función: defer mu.Unlock() después de Lock() sobrevive a los pánicos.
Para rutas "calientes" dentro de bucles, saca el bloqueo hacia afuera.
switch { case cond: sin etiqueta es la forma moderna.
Mismos semánticas, intención más clara.
No, un middleware de recuperación que envuelva el árbol es suficiente.
Capas duplicadas son redundantes, no dañinas.
Cuando el cuerpo excede una pantalla, necesita múltiples salidas o se repite en pruebas.
Las funciones nombradas mejoran los rastreos de pila y las pruebas unitarias.
Casi nunca en código de aplicación.
Prefiere etiquetas, auxiliares o tablas de despacho basadas en datos.
Eliminar la clave actual durante la iteración está definido.
Mantén la lógica de eliminación simple; extrae las claves primero si no estás seguro.
Prefiere errores para los llamadores que pueden reaccionar.
Reserva panic para un mal uso documentado que debería fallar en desarrollo.
staticcheck, govet, gosimple y revive marcan construcciones sospechosas.
Ejecuta a través de golangci-lint en CI.
deferrange - errores de captura de bucleVersiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC,
go fix modernizers- verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026