SwiftLo Básico

if / else if / else

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.