En este Tutorial Swift aprenderemos acerca de los valores opcionales, una característica especial del lenguaje Swift  que usaremos para indicar que una instancia puede o no contener un valor asociado, por esto cuando trabajamos con un valor opcional solamente podemos conocer dos cosas sobre este: o tiene un valor y está listo para ser usado o no tiene ninguno y es igual a nil.

A lo largo del artículo abordaremos sobre este tipo de valores pero antes comencemos por conocer que es nil.

Nil

El valor especial nil (en minúsculas) establece una variable opcional a un estado sin valor:

Hay que tener en cuenta  que nil no se puede utilizar con constantes y variables no opcionales. Si una constante o variable en el código tiene que trabajar con la ausencia de un valor bajo ciertas condiciones, siempre declarémosla como un valor opcional.

Un comportamiento importante de las variables opcionales y que está intrínsecamente relacionado con el uso del valor nil es que si usted define una variable como opcional sin proporcionar un valor por defecto, la variable se iguala automáticamente a nil, como veremos en el siguiente ejemplo:

Opcional

Una variable opcional se dice de aquella cuya declaración contiene el signo de interrogación (?) siguiendo al tipo de dato:

Como podemos ver la única diferencia con una variable normal es el signo de interrogación al final de la línea, esto es lo que vuelve la variable en Optional u opcional por su traducción al castellano. Una variable opcional no es más que un contenedor, un espacio de memoria que puede o no tener un valor asociado, aunque cuando no tiene un valor asociado el compilador asigna nil a la variable en cuestión.

Para entender del todo, veamos una variable opcional como una caja o un envoltorio cualquiera, donde al momento de su creación (de no darle un valor inicial) se introduce el valor especial nil. Una vez declarada esta variable, el contenido de la misma pasa a ser enmascarado (oculto) y como único podemos verificar su contenido es desenvolviendo implícitamente la misma. Esto lo podemos lograr mediante el signo de exclamación (!), de la siguiente forma:

Es importante aclarar que en caso de que esta variable contenga nil como valor asociado e intentamos desempaquetar su contenido, el compilador lanzará un “fatal error” mostrándonos el siguiente mensaje:

Para evitar este error, antes de hacer uso de la variable, tenemos que verificar si el contenido de la misma no es nil. Como muchos habrán imaginado, esto lo podemos lograr con el siguiente código:

…aunque el enfoque del código anterior es el correcto, se recomienda usar la sintaxis if let para tal fin, como podemos observar en el ejemplo a continuación:

A esta forma se le conoce como Optional Binding y se utiliza para averiguar si una variable opcional contiene un valor distinto a nil, de ser así, el valor de la misma pasa a estar disponible como una constante o variable temporal, como parte de una sola acción.

En la primera línea se evalúa si la variable opcional restaurantName es igual a nil, de lo contrario se desempaqueta su valor y se crea con este la variable temporal (solamente existe dentro del ámbito del if) restaurantNameUnwrapped del mismo tipo de la variable opcional. Ya dentro del if hacemos uso de la variable restaurantNameUnwrapped sin necesidad de usar el operador (!) ya que esta es una variable String (en este caso) normal.

Otro ejemplo de uso podría ser:

…la salida en pantalla sería:

…este resultado seguramente era el esperado por todos, pero si cambiamos dentro de las llaves “hola” por “10” veremos como la conversión sí sería satisfactoria ya que la expresión Int(texto) devolvería el número entero 10 en lugar de nil.

Desenvolviendo multiples valores opcionales

Para evitar tener que encadenar sentencias if-let pudiéramos seguir haciendo uso del Optional Binding y desenvolver varios valores opcionales en una sola línea:

…como podemos ver también podemos enlazar el binding de estos valores opcionales haciendo uso de la coma y repitiendo el mismo patrón y solamente ejecutando el código dentro de las llaves en caso de que ambas expresiones sean válidas, es decir que ninguno de estos valores sea nil.

La cláusula where

Tomando en cuenta el ejemplo anterior supongamos que solamente nos quisiéramos enfocar en el error 404 y obviar el resto, una manera de lograr esto sería hacer uso de la palabra clave where, la cual nos viene a ayudar con esta tarea a mi modo de ver de una manera más que óptima:

…la cláusula where aquí nos lleva un poco más allá en cuanto a la personalización que podemos lograr, filtrando y en este caso reduciendo el margen de ejecución cuando solamente queremos estar pendientes de los errores 404.

Opcionales implicitamente desenvueltas

Los valores opcionales desenvueltos de manera implícita funcionan de forma similar a los regulares, con la diferencia que no es necesario desenvolverlos para acceder a su valor y esto es bastante peligroso en caso de que este sea nil, por esta razón hay que hacer uso de ellos con mucha cautela.

En el siguiente ejemplo veremos como declararlo y hacer uso del mismo:

…en la primera línea declaramos nuestra variable opcional y en lugar de hacer uso del signo de interrogación ? hemos optado por el de exclamación !, el mismo que usamos en los opcionales regulares cuando los queremos desenvolver. Esto nos genera un tipo de opcional que como ya comenté no es necesario  desenvolver, sería así como una caja abierta, tal y como un tipo normal pero que puede tener nil como valor.

Encadenamiento de opcionales

Tal y como el Optional Binding este encadenamiento de opcionales nos brinda un mecanismo para consultar si un tipo opcional contiene un valor o no. Una diferencia importante entre estas dos formas de lograr lo mismo es que el encadenamiento de opcionales le permite al programador encadenar varias consultas dentro de un valor opcional. Es decir que si cada opcional en la cadena contiene un valor, la llamada a todos ha sido satisfactoria por lo que la consulta a la cadena retornará un opcional del tipo de dato esperado, así como si solamente uno de los opcionales en la cadena es nil toda la consulta devolverá nil.

En un ejemplo espero que esto quede más claro. Imaginemos que tenemos una aplicación con un mensaje personalizado para cuando nos encontremos ante un error 404, caso donde ejecutaremos ciertas sentencias en pos de añadir un texto más descriptivo al mensaje que se mostrará al usuario final. Algo similar:

…en este ejemplo la última línea es la de interés, en esta declaramos una variable que esperemos pueda almacenar el mensaje personalizado del error. Digo que esperamos ya que estamos haciendo una llamada a la variable opcional de tipo String errorDescription y a su vez al método uppercaseString. Lo que sucede aquí es que si errorDescription es nil debido a que el error no fue el 404, entonces la llamada al método uppercaseString generaría un error ya que lógicamente no tendría ningún texto para llevar a mayúsculas. Por este motivo hacemos uso nuevamente del símbolo de interrogación (?) y lo anteponemos al punto (.), asegurándonos así de que se haga la comprobación correspondiente antes de la llamada al método y devolviendo nil en caso de que no haya valor almacenado, tal y como es el caso del ejemplo. Cambien el código de error de 405 a 404 y verán el resultado esperado.

El operador de coalescencia

Una operación común cuando estamos trabajando con opcionales es tanto obtener el valor si es que tiene alguno o asignarle uno en caso de que sea nil. Usando optional binding haríamos algo así:

…pero hay un inconveniente, que para algo tan sencillo hemos escrito demasiado. Aquí es donde entra el operador de coalescencia de nil, compuesto por dos signos de interrogación (??). Veamos a continuación como quedaría el código anterior con este operador en sustitución al optional binding:

…así es, todo ha sido resumido en una sola línea, en el caso de que errorDescription no sea nil se inicializa la constante con el mensaje de error, de lo contrario con el mensaje “No error”.

Esto es todo, creo haber abordado la mayoría de los matices que componen los valores opcionales en Swift.

Para más información y ejemplos podemos dirigirnos a la documentación oficial de Swift (Inglés) en el sitio de desarrolladores de Apple.

Espero que todo cuanto se ha dicho aquí, de una forma u otra le haya servido de aprendizaje, de referencia, que haya valido su preciado tiempo.

Este artículo, al igual que el resto, será revisado con cierta frecuencia en pos de mantener un contenido de calidad y actualizado.

Cualquier sugerencia, ya sea errores a corregir, información o ejemplos a añadir será, más que bienvenida, necesaria!