Break en Go: ¿Rompe switch y select? Comparación de enfoques

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Break, que desconcierta: cómo Go revolucionó la «regla habitual del switch»

\n\n

Si alguna vez has programado en C, C++, Java o JavaScript, conoces el ritual: después de cada case en un switch hay que poner un break. De lo contrario, bienvenido al infierno del «fall-through», donde el código se ejecuta de un case a otro hasta que encuentra un break o el final de la estructura.

\n\n

Ahora imagina: te pasas a Go, escribes un switch y por costumbre pones un break al final de cada case. El código funciona. Pero te preguntas: «¿Realmente es necesario? ¿Y qué pasaría si lo quito?».

\n\n

Esta pregunta es una de las más populares en Stack Overflow en la sección de Go. Y la respuesta sorprende a los principiantes: en Go, break en switch y select no es obligatorio, pero existe y hace algo diferente. Analicémoslo con ejemplos para que nunca más te confundas.

\n\n

Go vs. C: el switch «invertido»

\n\n

En los lenguajes clásicos tipo C, switch funciona así:

\n\n
// Pseudocódigo C\nint x = 2;\nswitch(x) {\n    case 1:\n        printf("Uno");\n        break;  // Sin break — pasa al siguiente case\n    case 2:\n        printf("Dos");\n        break;\n    default:\n        printf("Otro");\n}\n// Salida: "Dos"
\n\n

Si quitas el break después de case 1, el programa imprimirá «UnoDos». Este comportamiento se llama fall-through y a menudo provoca errores.

\n\n

En Go decidieron: «¡Basta ya!» Por defecto, cada case en switch termina automáticamente y no necesita break:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    x := 2\n    switch x {\n    case 1:\n        fmt.Println("Uno")\n        // break no es necesario — salimos del switch\n    case 2:\n        fmt.Println("Dos")\n        // break no es necesario\n    default:\n        fmt.Println("Otro")\n    }\n    // Salida: "Dos"\n}
\n\n

Pero si igual pones un break — no pasa nada, el código simplemente sale del switch antes. Sin embargo, ¿para qué poner un break extra si ese es el comportamiento por defecto?.

\n\n

¿Y el fall-through?

\n\n

Si necesitas «caer» al siguiente case, Go ofrece una palabra clave explícita: fallthrough:

\n\n
switch x {\ncase 1:\n    fmt.Println("Uno")\n    fallthrough  // Decimos explícitamente: «Quiero ir al siguiente case»\ncase 2:\n    fmt.Println("Dos")\ndefault:\n    fmt.Println("Otro")\n}\n// Con x=1 imprimirá: "Uno" y "Dos"
\n\n

Nota: fallthrough solo funciona para el siguiente case y no en cadena. Esto se hizo a propósito para evitar errores accidentales.

\n\n

Select: el «hermano» multicanal de switch

\n\n

Go tiene una construcción única: select. Es similar a switch, pero solo funciona con canales. Y aquí también existe break, pero con un truco.

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc main() {\n    ch1 := make(chan string)\n    ch2 := make(chan string)\n\n    go func() {\n        time.Sleep(1 * time.Second)\n        ch1 <- "Hola desde el canal 1"\n    }()\n    go func() {\n        time.Sleep(2 * time.Second)\n        ch2 <- "Hola desde el canal 2"\n    }()\n\n    select {\n    case msg1 := <-ch1:\n        fmt.Println(msg1)\n        break  // Salida de select\n    case msg2 := <-ch2:\n        fmt.Println(msg2)\n        break  // Salida de select\n    case <-time.After(3 * time.Second):\n        fmt.Println("Tiempo de espera agotado")\n    }\n}
\n\n

Aquí break tampoco es obligatorio — select termina después de ejecutar un case. Pero ¿para qué sirve?. La respuesta: ¡para salir de un bucle externo!

\n\n

La principal «característica» de br

Blogs

Book Recommendations