Optionals en Swift: qué son, por qué existen y cómo usarlos sin miedo

Un optional es un tipo que envuelve otro añadiendo la posibilidad de ausencia. String? significa «un String o ningún valor». Bajo el capó es el enum Optional<Wrapped> con casos .some y .none:

var nombre: String? = "Ana"
nombre = nil   // válido

var apellido: String = "García"
// apellido = nil  // Error de compilación

// El compilador impide usar el optional sin desenvolver
// print(nombre.uppercased())  // Error: value of optional type must be unwrapped

if let y guard let

func saluda(nombre: String?) {
    // guard let: salida temprana si nil
    guard let n = nombre else {
        print("Sin nombre")
        return
    }
    print("Hola, (n)")
}

saluda(nombre: "Pedro")  // Hola, Pedro
saluda(nombre: nil)      // Sin nombre

// Swift 5.7+: shorthand (misma etiqueta)
if let nombre {
    print(nombre)  // desenvuelto, tipo String
}

Nil-coalescing ??

Proporciona un valor por defecto cuando el optional es nil. Se puede encadenar para múltiples fuentes:

let entrada: String? = nil
let nombre = entrada ?? "Invitado"
print(nombre)  // Invitado

// Encadenado
let a: Int? = nil
let b: Int? = nil
let c = a ?? b ?? 0   // 0

Optional chaining con ?.

struct Direccion { var ciudad: String }
struct Usuario  { var direccion: Direccion? }

let u: Usuario? = Usuario(direccion: Direccion(ciudad: "Bilbao"))
print(u?.direccion?.ciudad ?? "—")   // Bilbao

let fantasma: Usuario? = nil
print(fantasma?.direccion?.ciudad ?? "—")  // —

// Llamar métodos opcionales
let s: String? = "hola"
print(s?.uppercased() ?? "")  // HOLA

Cuándo usar forced unwrap

El operador ! fuerza el desenvolvimiento sin comprobar nil; si lo es, el programa se detiene con un error fatal. Úsalo solo cuando tengas certeza absoluta de que el valor existe y no puedas usar if let ni guard let. En código de producción, el forced unwrap es casi siempre evitable y preferiblemente se sustituye por guard let:

let valor: Int? = 42
print(valor!)  // 42

// Pattern más seguro
guard let v = valor else { fatalError("valor nulo") }
print(v)  // 42

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP