OPCIONALES en Swift en Español - Curso Swift | Tutorial Swift
Opcionales en Swift. Una de las ventajas de Swift es el uso de opcionales. Un tipo que representa o un valor o nil (ausencia de valor). Es muy útil trabajar con opcionales como verás en el post.
Tabla de contenido
Se usan los opcionales cuando el valor en una variable puede estar ausente. Un opcional representa dos posibilidades: ya sea porque hay un valor o porque aún no se ha asignado ningún valor.
El opcional es como una caja, la caja puede tener un valor o estar vacía
Esto se ve mejor con un ejemplo. Los Int en Swift tiene un inicializador que acepta un String. Si el valor que le pasamos es "123" entonces el resultado será 123, pero si el valor que le pasamos es "Hola", el contenido de la variable será nil (ya que no podemos transformar "Hola" en un número)
Como el inicializador puede fallar, el tipo de myNumber es Int? y en caso de fallar su valor sería nil. Recordamos que un opcional puede o no puede tener un valor.
En realidad un Opcional es un Enum, en el que podemos tener un valor de un tipo concreto o no podemos tener nada. Una posible representación de cómo funciona un opcional sería:
Cuando asignamos .none es como si estuvieramos diciendo que el valor es nil. Y cuando asignamos .some("Hello") es cuando le asignamos un valor de un tipo concreto. El código anterior es para que te hagas una idea, entraremos más en detalle sobre genéricos en siguientes posts.
Cuando queremos asignar la ausencia de valor en un opcional, podemos asignarle nil. Y más tarde, asignarle el valor que queramos a medida que interactueamos con nuestro programa.
var myInt: Int? = nil
myInt = 2
Si defines una variable como opcional, no hace falta que le asignes el valor de nil, ya que se lo asigna por defecto.
Los opcionales tienen sentido con variables y no con constantes. En una constante no podemos modificar su valor. Por lo tanto si hiciéramos lo siguiente, no podríamos cambiar su valor en el ciclo de nuestro programa.
let myConstant: Int? = nil
Si intentamos asigna un valor a myConstant obtendríamos el siguiente error
Cannot assign to value: 'myConstant' is a 'let' constant
Obtener el valor de un Opcional en Swift
Manera segura
Volvamos al primer ejemplo, ¿cómo podemos obtener el valor que hay dentro de un opcional para poder usarlo? Lo podemos hacer de la siguiente manera usando Optional Binding.
let myStringNumber = "123"
let myNumber = Int(myStringNumber)
if let value = myNumber {
print("Int \(value)")
}
Lo que acabamos de hacer es, en el caso de tener un valor sacamos el valor del opcional y lo asignamos en value. Esto es una manera segura de sacar el valor de los opcionales.
Otra manera de obtener el valor de un opcional de manera segura es usando map
myNumber.map { value in
print("Int \(value)")
}
Es decir, si hay un valor en myNumber entrará dentro del closure del map y se verá su valor printado en la pantalla.
Force Unwrapp en Swift
Otra manera de sacar el valor de un opcional es usando la exclamación !. El problema de extraer el valor de esta manera es que no es seguro y si no hay ningún valor la aplicación crasheará. Debemos estar muy seguros de que hay un valor asignado a esa variable antes de hacer un Force Unwrapp
// FUNCIONA
let myStringNumber = "123"
let myNumber = Int(myStringNumber)
myNumber!
// NO FUNCIONA
let myStringNumber = "Hola"
let myNumber = Int(myStringNumber)
myNumber!
En el segundo caso, obtenemos un Fatal Error
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Obtenemos este error porque no hemos podido crear un Int a partir de la string "Hola". Tiene todo el sentido del mundo.
Operador nil coalescing en Swift
Otra manera de obtener el valor de un opcional es con el operador ??. Éste es un operador seguro ya que si no hay ningún valor dentro de la variable, se especifica un valor por defecto.
let helloString = "Hola"
let myNumberFails = Int(helloString)
let defaultNumber = myNumber ?? 1
Como myNumber es nil, se coge el valor que aparece a la derecha del operador ??. Por lo tanto el valor que se asignaría a defaultNumber es 1.
Hay más maneras de sacar valores de los opcionales, esto es una leve pincelada pero iremos viendo más ejemplos en otros posts.
Y para acabar, comentar que cualquier tipo en Swift puede ser opcional.