← Volver al blog

if / else if / else

Domina if, switch, bucles y el poderoso guard de Swift. Control de flujo con el estilo del Swift moderno que se usa en producción hoy.

El control de flujo determina qué camino toma tu código según las condiciones del momento. En este post cubrimos if, switch, bucles y el poderoso guard — una herramienta de Swift moderno que cambia completamente cómo estructuras tus funciones.

if / else if / else

La estructura condicional básica. En Swift las condiciones no necesitan paréntesis (aunque puedes ponerlos), pero las llaves {} son obligatorias siempre.

let temperatura = 28

if temperatura > 35 {
    print("Hace mucho calor")
} else if temperatura > 20 {
    print("Temperatura agradable")  // se imprime esto
} else {
    print("Hace frío")
}

// En Swift 5.9+ puedes usar if como expresión para asignar un valor
let descripcion = if temperatura > 35 {
    "Caluroso"
} else if temperatura > 20 {
    "Agradable"
} else {
    "Frío"
}
print(descripcion)  // "Agradable"

switch — mucho más poderoso que en otros lenguajes

El switch de Swift es significativamente más potente que en lenguajes como Java o C. No necesita break, soporta rangos, tuplas y pattern matching avanzado. Cada case debe ser exhaustivo — si no cubres todos los casos, el compilador te lo exige.

// Switch básico — no necesita break
let diaSemana = 3
switch diaSemana {
case 1: print("Lunes")
case 2: print("Martes")
case 3: print("Miércoles")  // se imprime esto
case 4: print("Jueves")
case 5: print("Viernes")
case 6, 7: print("Fin de semana")  // múltiples valores en un case
default: print("Día inválido")
}

// Switch con rangos
let nota = 78
switch nota {
case 90...100: print("Sobresaliente")
case 70..<90:  print("Notable")       // se imprime esto
case 50..<70:  print("Suficiente")
default:       print("Insuficiente")
}

// Switch con where (condición adicional)
let valor = 15
switch valor {
case let x where x % 2 == 0:
    print("\(x) es par")
case let x where x % 2 != 0:
    print("\(x) es impar")  // se imprime esto
default:
    break
}

Bucle for-in

El bucle más usado en Swift. Itera sobre colecciones, rangos y secuencias. Es limpio, seguro y expresivo.

// Iterar un rango
for i in 1...5 {
    print(i)
}

// Iterar un array
let idiomas = ["Swift", "Kotlin", "Python"]
for idioma in idiomas {
    print(idioma)
}

// Ignorar el índice con _
for _ in 1...3 {
    print("Repetición")
}

// Iterar con índice usando enumerated()
for (indice, idioma) in idiomas.enumerated() {
    print("\(indice + 1). \(idioma)")
}

// Iterar un diccionario
let capitales = ["México": "CDMX", "España": "Madrid", "Argentina": "Buenos Aires"]
for (pais, capital) in capitales {
    print("\(pais)\(capital)")
}

Bucles while y repeat-while

Se usan cuando no sabes de antemano cuántas iteraciones necesitas. while evalúa la condición antes de ejecutar, repeat-while la evalúa después (garantiza al menos una ejecución).

// while — evalúa primero
var contador = 0
while contador < 5 {
    print(contador)
    contador += 1
}

// repeat-while — ejecuta al menos una vez
var intento = 0
repeat {
    print("Intento \(intento)")
    intento += 1
} while intento < 3

break y continue

break detiene el bucle por completo. continue salta a la siguiente iteración sin ejecutar el resto del código del ciclo actual.

// break — detiene el bucle
for numero in 1...10 {
    if numero == 6 { break }
    print(numero)  // imprime 1, 2, 3, 4, 5
}

// continue — salta esa iteración
for numero in 1...10 {
    if numero % 2 == 0 { continue }
    print(numero)  // imprime solo los impares: 1, 3, 5, 7, 9
}

guard — la joya de Swift moderno

guard es uno de los elementos más importantes de Swift y está ausente en la mayoría de otros lenguajes. Su función es validar condiciones al inicio de una función y salir inmediatamente si no se cumplen. Esto elimina el anidamiento excesivo de if y hace el código mucho más legible.

// Sin guard — el "pyramide de la muerte"
func procesarSinGuard(nombre: String?, edad: Int?) {
    if let nombre = nombre {
        if let edad = edad {
            if edad >= 18 {
                print("Procesando: \(nombre), \(edad) años")
            } else {
                print("Menor de edad")
            }
        } else {
            print("Edad inválida")
        }
    } else {
        print("Nombre inválido")
    }
}

// Con guard — lineal, fácil de leer
func procesarConGuard(nombre: String?, edad: Int?) {
    guard let nombre = nombre else {
        print("Nombre inválido")
        return
    }
    guard let edad = edad else {
        print("Edad inválida")
        return
    }
    guard edad >= 18 else {
        print("Menor de edad")
        return
    }

    // Aquí sabemos que nombre y edad son válidos
    print("Procesando: \(nombre), \(edad) años")
}

procesarConGuard(nombre: "Usuario", edad: 25)  // "Procesando: Usuario, 25 años"
procesarConGuard(nombre: nil, edad: 25)         // "Nombre inválido"
procesarConGuard(nombre: "Usuario", edad: 15)   // "Menor de edad"

La regla es simple: usa guard para los casos de error o condiciones que deben cumplirse para que el código tenga sentido. Todo lo que venga después del guard ya está validado — el camino feliz queda limpio y plano.

Resumen

  • if/else: condiciones simples; en Swift 5.9+ también puede usarse como expresión para asignar valores.
  • switch: exhaustivo, sin break, soporta rangos y pattern matching con where.
  • for-in: el bucle principal de Swift, itera sobre cualquier secuencia.
  • while / repeat-while: cuando el número de iteraciones es desconocido.
  • guard: valida condiciones al inicio y sale si no se cumplen — elimina el anidamiento y mejora la legibilidad.

En el siguiente post llegamos a uno de los temas más importantes y característicos de Swift: los Opcionales.