control-flujo-switch-go

Switch en Go: casos múltiples, lógicos y sin condición

  • 4 min

Un switch en Go es una estructura de selección para elegir entre varios casos posibles sin encadenar una ristra interminable de if else.

Si vienes de lenguajes como C, C++, Java o C#, seguramente tienes una relación de amor-odio con la sentencia switch. Es útil, sí, pero tiene una famosa trampa: si se te olvida poner un break al final de un case, la ejecución “cae” (fallthrough) al siguiente caso, provocando bugs que a veces son difíciles de detectar.

En Go, el switch evita esa caída implícita y además permite agrupar valores, evaluar condiciones y declarar una variable auxiliar.

El switch básico

Vamos con la diferencia más importante. En Go, el break está implícito.

Cuando Go encuentra un case que coincide, ejecuta el código de ese bloque y automáticamente sale del switch. No necesitas escribir break en cada caso.

package main

import "fmt"

func main() {
    dia := "lunes"

    switch dia {
    case "lunes":
        fmt.Println("¡Ánimo, empieza la semana!")
        // Aquí hay un 'break' automático. No sigue ejecutando.
    case "viernes":
        fmt.Println("¡Ya casi es finde!")
    default:
        fmt.Println("Un día normal...")
    }
}
Copied!

Esta simple decisión de diseño elimina una de las fuentes de errores más comunes en la historia de la programación en C/C++.

Casos múltiples (Listas)

¿Qué pasa si queremos ejecutar el mismo código para varios valores? En otros lenguajes tendrías que apilar case uno encima de otro. En Go, simplemente los separamos por comas.

func main() {
    letra := 'e'

    switch letra {
    case 'a', 'e', 'i', 'o', 'u': // ¡Mucho más limpio!
        fmt.Println("Es una vocal")
    default:
        fmt.Println("Es una consonante")
    }
}
Copied!

switch sin expresión

Otra diferencia útil: si omites la variable después de switch, Go asume que estás evaluando true.

Esto convierte al switch en una alternativa más clara a una cadena larga de if, else if y else.

Con if-else (Ruidoso):

t := 15
if t < 10 {
    fmt.Println("Frío")
} else if t >= 10 && t < 25 {
    fmt.Println("Templado")
} else {
    fmt.Println("Calor")
}
Copied!

Con switch (Elegante):

t := 15
switch { // Equivale a 'switch true'
case t < 10:
    fmt.Println("Frío")
case t >= 10 && t < 25:
    fmt.Println("Templado")
default:
    fmt.Println("Calor")
}
Copied!

Esta forma es la idiomática en Go para sustituir cadenas complejas de condicionales. Es más legible porque alinea verticalmente las condiciones.

Inicialización corta

Al igual que vimos con el if, el switch admite una sentencia corta de inicialización. Podemos ejecutar una función, obtener un valor y evaluarlo, limitando el alcance de la variable.

package main

import (
    "fmt"
    "time"
)

func main() {
    // Declaramos 'hoy' dentro del propio switch
    switch hoy := time.Now().Weekday(); hoy {
    case time.Saturday, time.Sunday:
        fmt.Println("Es fin de semana, descansa.")
    default:
        fmt.Println("Toca trabajar, hoy es", hoy)
    }

    // Aquí 'hoy' ya no existe. El scope está limpio.
}
Copied!

fallthrough: continuar con el caso siguiente

¿Y si por alguna extraña razón necesitas que la ejecución continúe al siguiente caso (el comportamiento por defecto de C)?

Go te permite hacerlo, pero te obliga a ser explícito usando la palabra clave fallthrough.

n := 1

switch n {
case 1:
    fmt.Println("Uno")
    fallthrough // Obliga a entrar en el caso siguiente SIN comprobar la condición
case 2:
    fmt.Println("Dos")
}
// Salida:
// Uno
// Dos
Copied!

El uso de fallthrough es muy poco común en Go. Si te ves usándolo mucho, probablemente deberías replantear la lógica de tu código.

Además, ten cuidado: fallthrough salta al siguiente caso sin evaluar su condición.

Diferencias frente al switch clásico

Estas son las principales diferencias frente al switch de C o C++:

CaracterísticaC / C++ / JavaGo
BreakNecesario (manual)Automático (implícito)
FallthroughPor defecto (peligroso)Explícito (seguro)
ExpresionesSolo constantesCualquier expresión válida
Casos múltiplesApilando case:Comas case 1, 2:
Sin condiciónNo permitidoSí (reemplaza if-else)