Swift y el concepto de opcionales

Archivada en Desarrollo Web

Swift y el concepto de opcionales

Swift tiene un concepto muy importante que son los opcionales. Para los que desarrollan en JavaScript este es un concepto similar a las promesas. Como es muy frecuente, debemos darnos el tiempo de usarlo y dominarlo.

Los opcionales se usan cuando un valor puede estar ausente. Se define de la siguiente manera.

Definición de Opcional

Un opcional es una variable que puede o no tener un valor asignado a ella.

Hay ocaciones en que una constante o una variable podría no tener un valor, por ejemplo, cuando se llena un formulario. Recordemos que Swift es un lenguaje compilado por lo tanto, desde el diseño debemos asegurar que sabemos que hacer si el usuario llena mal un campo (es parte de las validaciones).

Veamos este ejemplo que usa el inicializador llamado Int(), que convierte, en este caso un texto String en un entero tipo Int.

var strText = "43"
let intEntero = Int(strText)

En este caso, el tipo intEntero se infiere como tipo Int?, es decir opcional Entero con el valor 43. El signo de interrogación indica que el es un opcional, lo que significa que el valor de la variable o constante puede estar ausente. Veamos el siguiente ejemplo:

var strTexto = "Hola Mundo"
let intEntero = Int(strText)

El ejemplo anterior tiene un problema: no podemos convertir Hola Mundo desde un String a un Int. Por lo tanto, se dice que el valor de intEntero está ausente o es nil (o sea nulo), porque el tipo de datos de la variable intEntero se infirió com Int opcional.

El inicializador de enteros Int() puede fallar al regresar un valor, por eso el método regresa un Int opcional, en lugar de un tipo Int. De nuevo, el signo de interrogación indica que el valor de un variable es de tipo opcional, lo que significa que puede contener un valor entero o puede que no contenga nada1.

Podríamos definir la variable como tipo Int opcional de la siguiente manera:

let intEntero: Int? = Int(strText)

En Swift 4 nil es la ausencia de un valor. Los opcionales de cualquier tipo pueden ser nil, no solo los tipos básicos.

Desempaquetando opcionales

Ya que los opcionales pueden tener o no un valor, hay que verificarlos antes de poder usarlos. Esto lo podemos hacer usando un if para determinar si el opcional contiene un valor, comparando la variable contra nil. Si el opcional tiene un valor, se considera que “no es igual que” nil.

var strTexto = "Hola Mundo"
let intEntero = Int(strTexto)
// intEntero no tiene un valor o su valor esta ausente
if intEntero != nil {
  print("intEntero contiene un valor entero.")
} else {
  print("intEntero no contiene un valor entero.")
}

Ahora que hemos agregado una verificación para asegurarnos que el opcional contiene o no un valor, podemos acceder a este valor agregando un signo de exclamación (!) al final del nombre del opcional. El ! significa que nos hemos asegurado que la variable opcional tiene un valor y podemos usarlo. Esto se llama desempaquedado forzoso del valor del opcional.

var strTexto = "Hola Mundo"
let intEntero = Int(strTexto)
// intEntero no tiene un valor o su valor esta ausente
if intEntero != nil {
  print("intEntero contiene un valor entero. Es este \(intEntero!)")
} else {
  print("intEntero no contiene un valor entero.")
}

Enlace opcional

Se puede verificar si un opcional contiene un valor y si es así, asignarlo a una constante o una variable en un solo movimiento. Esto se llama enlace opcional y puede usarse con sentencias if y while para determinar si un opcional tiene un valor y extraer ese valor en una variable o constante.

let strOpcional: String? = "Hola mundo"
if let strEnlace = strOpcional { 
  print("strEnlace contiene un valor que es: \(strEnlace)")
}

Si queremos asignar el opcional a una variable para poder manipularla, podemos asignar el opcional a un var:

let strOpcional: String? = "Hola Mundo"
if var strEnlace = strOpcional {
  print("strEnlace contiene un valor que es: \(strEnlace)")
}

Hay que observar que en los ejemplos anteriores no necesitamos usar el !. Si la conversión fue exitosa, la variable o constante fue inicializada con el valor contenido en el opcional.

En otros lenguajes el símbolo ! implica negación y se coloca antes de la variable o constante, pero en el desempaquetado forzoso se coloca después de la constante o variable con opcional.

Desempaquetado implícito de opcional

Hay ocasiones en que el valor de una variable puede establecerse cuando sabes que el opcional siempre tendrá un valor. En esos casos, es útil eliminar la necesidad de verificar y desempaquetar el opcional cada vez que se necesita acceder a su valor. Esta clase de opcionales se llaman opcionales implícitamente desempaquetados.

Debido a la estructura de un programa, podemos saber que el opcional tiene un valor, y concederle permisos para desempaquetar su valor de forma segura cada vez que tengamos que acceder a él. En estos casos, no necesitamos usar el !; en su lugar lo colocamos después del tipo de opcional cuando lo declaremos. Veamos el siguiente ejemplo:

var strOpcional: String? = "Mi texto opcional"
var textDesempaquetadoForzoso: String =  strOpcional!  // requiere un !
var otroTextoOpcional: String! = "Opcional con desempaquetado implícito"
var opcionalaDesempaquetadoImplicito = otroTextoOpcional  // no necesitamos un !

Después de leer lo anterior y hacer algunas pruebas, creo que necesito mas práctica.


  1. En el idioma español, la doble negativa sigue siendo negativa. 

Javier Sanchez Toledano

Auditor Líder ISO 9000 ● Desarrollo Web Full Stack ● Django/Python ● JavaScript · NodeJS · Angular · VueJS · EmberJS ● Swift 4 ● WordPress · Genesis Framework ● Lector ● Fotografo aficionado ● Generación X ● Soy de Tlaxcala

Tlaxcala, México

Comentarios