DEV Community

David Goyes
David Goyes

Posted on

Swift #6: Opcionales

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

Se puede usar guard/else junto con "Optional Binding".

guard let value else {
  return
}
guard var value else {
  return
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Pattern Matching (case let)

let optionalValue: Int? = 77
switch optionalValue {
case let value?:
    print(value)
case nil:
    print("nil")
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)