Algunas veces es necesario indicar la ausencia de valor de una variable. Para estos casos, Swift tiene el modificador ? que convierte cualquier tipo de dato en opcional. Una variable opcional puede tener un valor o estar vacía (su valor es nil).
var result: Int? // Asume nil por defecto
result = 1
result = nil
Inicialización diferida ("Implicitly Unwrapped Optionals")
En ocasiones, una variable opcional siempre tendrá un valor cuando se use, pero no se sabe qué valor configurarle inicialmente.
Estas variables opcionales se declarar con ! en lugar de ?, y son tratadas como requeridas cuando se usan dentro de una expresión.
var x: Int!
x = 3
var result = x * 2 // 6
Notar que no es necesario volver a usar ! al leer el valor de x.
Desempaquetado de opcionales
Desempaquetado Forzado ("Forced unwrap")
Solo cuando se esté 100% seguro de que el valor de un opcional no es nil, se puede extraer con !.
let optionalValue: Int? = 5
let value = optionalValue! // value: Int = 5
Optional Binding (if let/var, guard let/var)
En ocasiones se necesita verificar que el valor de un opcional sea distinto de nulo, para luego usarlo. Manualmente haríamos lo siguiente:
var count = 0
let input: Int? = 5
if input != nil {
let safeInput = input!
count += safeInput
}
Swift ofrece una sintaxis conveniente que valida el opcional y lo desenvuelve al mismo tiempo, que se llama "Optional Binding".
var optionalValue: Int? = 5
if let value = optionalValue {
print(value)
}
if var value = optionalValue {
print(value)
}
Si el valor del opcional es distinto de nil, se asigna su valor a la variable/constante value y se ejecuta el bloque entre llaves.
Como las variables y constantes declaradas en un bloque de código solo están disponibles para él, entonces se pueden declarar las constantes del "Optional Binding" con el mismo nombre que la variable.
var value: Int? = 5
if let value = value {
print(value)
}
if var value = value {
print(value)
}
Cuando el nombre de la constante/variable del "Optional binding" sea igual que el nombre de la constante/variable opcional, entonces se puede recortar la sintaxis del "Optional Binding" así:
var value: Int? = 5
if let value {
print(value)
}
if var value {
print(value)
}
Se puede usar guard/else junto con "Optional Binding".
guard let value else {
return
}
guard var value else {
return
}
En caso de nombrar la constante/variable del "Optional Binding" con el mismo nombre que la constante/variable opcional, hay que tener en cuenta que NO son la misma variable, es decir: hacen alusión a distintas posiciones de memoria.
El if del "Optional binding" también permite evaluar otras condiciones, por ejemplo:
var value: Int? = 5
if let value, value > 3 {
print(value)
}
Sin embargo, tener en cuenta que el condicional de Swift funciona con evaluación de cortocircuito, por lo cual, la segunda condición (i.e. value > 3) no se ejecutará si la primera no pasa (i.e. value == nil).
Optional chaining
let optionalName = optionalValue?.name
Nil-Coalescing (??)
Devuelve un valor por defecto si es nil. Las dos operaciones son equivalentes:
let age: Int? = 19
let realAge = age != nil ? age! : 0 // 19
let realAge2 = age ?? 0 // 19
let age2: Int? = nil // nil
let realAge3 = age2 ?? 5 // 5
Pattern Matching (case let)
let optionalValue: Int? = 77
switch optionalValue {
case let value?:
print(value)
case nil:
print("nil")
}
Top comments (0)