La Palabra Clave Try

Tutorial Swift – La Palabra Clave Try

Hola amigos, en este Tutorial Swift aprenderemos sobre un tópico relacionado con el manejo de errores, me refiero a la palabra clave try y sus dos variantes. La versión estándar de try (por así decirlo) ya la hemos visto en el anterior y extenso artículo, aun así hablaremos sobre esta y terminaremos con los dos nuevos estados que puede adoptar.

Como ya todos saben tengo la costumbre de apoyar mis explicaciones en ejemplos prácticos, así que para comenzar quiero mostrar una versión inicial del código de ejemplo (parte de la documentación oficial de Swift (en Inglés)) con el cual estaremos trabajando:

Comenzamos con una enumeración de nombre VendingMachineError que incorpora el protocolo Error y donde se definen los 3 errores que podrán ser emitidos, junto a esta tenemos una estructura de nombre Item donde se declaran dos variables una relacionada al precio (price) de cierto producto (item) y la otra representa la cantidad (count) a comprar.

Luego definimos la clase VendingMachine (Máquina Expendedora) donde declaramos un Dictionary de nombre inventory y que almacena los productos que oferta la máquina, así como su precio y cantidad de unidades. También contamos con una variable llamada coinsDeposited cuyo valor corresponde a las monedas introducidas por el cliente y por último el método vend que recibe como parámetro el nombre del producto a comprar y que está marcado como throws, es decir que puede emitir errores. Estos errores son aquellos comprendidos en la enumeración y que en este método se verifican uno a uno mediante el uso de guard.

Como ya sabemos que el método vend puede propagar un error, cualquier código que lo llame tiene que tener en cuenta este factor y manejar / capturar la propagación del error en pos de darle una salida “elegante” y óptima. Para esto en el artículo anterior habíamos visto la sentencia do-catch pero también podemos optar por try? y try!, dos nuevas versiones o variantes de try (otro ejemplo de la versatilidad del lenguaje Swift) y que a continuación explicaré.

Antes necesitamos agregar las siguientes líneas de código al ejemplo anterior:

…al inicio de estas tenemos un diccionario de nombre favoriteSnacks donde hemos mapeado a tres personas con sus respectivos Snacks favoritos. Luego nos encontramos a la función buyFavoriteSnack la cual nos ayuda con la compra de nuestro Snack dado el nombre de la persona interesada y una máquina expendedora. Dentro de esta función en la línea 13 hacemos una llamada con try al método vend pero como podemos observar no hemos usado la sentencia do-catch. Esto se debe a que por alguna razón no queremos manejar el error dentro de la función buyFavoriteSnack y aprovechamos que esta también ha sido marcada como throws.

Haciendo esto los errores que se generen producto del método vend serán propagados al nivel superior que en este caso sería al ámbito desde donde se efectuó la llamada a la función buyFavoriteSnack:

…la salida en pantalla sería:

La línea 7 da comienzo a todo con la ejecución de la función buyFavoriteSnack, esta a su vez se encuentra dentro de un bloque do y seguido a este las sentencias catch con los distintos códigos de respuesta para cada error en específico. Esta sentencia do-catch constituye el final de la propagación de errores que han sido emitidos desde la función vend.

Convirtiendo Errores en Valores Opcionales

En este punto veremos la primera variante de try que sería try?, y que nos permite convertir un error emitido en un valor opcional, es decir, que si un error es emitido mientras se evalúa la expresión try? entonces el valor de esta será nil.

En el siguiente ejemplo el uso de try? nos permite manejar los errores de forma efectiva en este caso donde deseamos tratarlos a todos de la misma manera:

En este ejemplo hemos usado varios métodos de obtención de datos y en el caso de que todos estos fallen pues retornamos nil.

Inhabilitando la Propagación de Errores

En ocasiones conocemos que una función no lanzará ningún error en tiempo de ejecución y podemos escribir try! y con esto inhabilitar la propagación de errores, es decir, que si un error de hecho ocurre, ningún bloque do-catch será capaz de capturarlo, en este punto de no retorno obtendremos un error de tiempo de ejecución.

En este ejemplo se hace uso de la función loadImage(atPath:) la cual carga una imagen desde una dirección local específica o emite un error en caso de que esto no pueda llevarse a cabo, pero como la imagen forma parte de la aplicación es más que evidente que no se emitirá un error en tiempo de ejecución, por este motivo es apropiado inhabilitar esta funcionalidad.

El uso y razón de existencia de try? y try! se pudiera resumir en más flexibilidad a la hora de escribir código y por ende un manejo de errores quizás más efectivo ante ciertos entornos / circunstancias.

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!