SwiftIntermedio20 oct 2025
El nil más escurridizo de Swift: ¿Un nil que NO es nil?
snippet.swift
let optionalIntNil: Int? = nil
let optionalAnyWithOptionalIntNil: Any? = optionalIntNil
print("optionalIntNil es nil: \(optionalIntNil == nil)")
print("optionalAnyWithOptionalIntNil es nil: \(optionalAnyWithOptionalIntNil == nil)")
print("optionalAnyWithOptionalIntNil realmente contiene: \(optionalAnyWithOptionalIntNil)")¿Qué crees que imprime?
✅ Salida Esperada
optionalIntNil es nil: true
optionalAnyWithOptionalIntNil es nil: true
optionalAnyWithOptionalIntNil realmente contiene: nil⚠️ Salida Real
optionalIntNil es nil: true
optionalAnyWithOptionalIntNil es nil: false
optionalAnyWithOptionalIntNil realmente contiene: Optional(nil)¿Por qué pasa esto?
¡Prepárate para la gimnasia mental, porque Swift tiene un `nil` que desafía la lógica! 🤯
Aquí, `optionalIntNil` es un `Int?` que, como su nombre indica, es un glorioso `nil`. Hasta aquí, todo bien, ¿verdad?
Pero, cuando asignamos ese `nil` a una variable de tipo `Any?`, ¡la cosa se pone interesante! Swift no simplemente pasa el `nil` puro. En su lugar, el `Optional<Int>.none` (que es como se representa un `nil` para un `Int?`) es **envuelto** dentro de otro `Optional<Any>`.
Piensa en ello como una caja de regalo (`Optional<Any>`). Dentro de esa caja, pones OTRA caja de regalo (`Optional<Int>`), ¡y esa segunda caja es la que está vacía (contiene `nil`)! 🎁➡️📦(🎁(vacío)).
Entonces, ¿la caja exterior (`optionalAnyWithOptionalIntNil`) está vacía? ¡Claro que no! Contiene una caja vacía. Por eso, al preguntar si `optionalAnyWithOptionalIntNil == nil`, Swift dice: "¡No, amigo! Tengo algo aquí, aunque sea un `nil` envuelto." Es un `Optional` que contiene `nil`, ¡no un `nil`! Este comportamiento es un clásico "gotcha" al trabajar con tipos genéricos o `Any`. ¡Cuidado!
Conceptos relacionados
optionalstype-erasurenil-semantics