Ir al contenido principal

Swift: ‘some’ y los tipos opacos

Una de las características que más llamó la atención cuando Apple presentó SwiftUI fue esa sentencia some que aparecía en la propiedad body necesaria para implementar el protocolo View en el que se basa todo el framework. Esto es necesario para SwiftUI pero es una de las nuevas características del lenguaje Swift 5.1 y se denominan tipos opacos.


Definición informal

Seguro que no va a ser la definición más formal pero al menos es la que yo entiendo. Porque siendo sincero, se me ha atragantado un poco comprender el funcionamiento y sobretodo el fin que persiguen los tipos opacos en Swift.

Un tipo opaco se aplica cuando una función (o variable calculada) retorna un protocolo y obliga a que el tipo devuelto sea conocido en tiempo de compilación y siempre sea el mismo. Es decir, si mi función devuelve -> some Protocolo y Tipo1 y Tipo2 se conforman a ese protocolo, no puedo devolver unas veces Tipo1 y otras Tipo2, tengo que devolver uno u otro siempre. Otra forma de verlo es que el llamante de la función o variable calculada necesita que el tipo no varíe en tiempo de ejecución.

Ejemplo

Si os acaba de explotar la cabeza, como a mí cuando leía las distintas definiciones por la red, creo que con un pequeño ejemplo es más fácil de asimiliar. Tenemos el protocolo Persona y los tipos Pintor y Escritor definidos así:


Ahora vamos a crear un tipo de cada y una enumeración que represente las dos opciones. Además seleccionamos una de las opciones (en seguida veremos para qué).


Luego creamos la siguiente propiedad calculada (si no va a recibir parámetros, ¿para qué vamos a hacer una función con los bonito que queda así?). Devolverá un tipo conformado a Persona, pero debido a la condición que hemos escrito, puede ser de tipo Pintor o Escritor.

Esto es perfectamente válido, no hay errores al compilar y se ejecuta sin problemas. Y estaréis pensado: ¿para qué me cuentas entonces este rollo? Porque la cosa cambia si añadimos some y hacemos que devuelva un tipo opaco.


Y vaya si cambia porque ni compila… El error es Function declares an opaque return type, but the return statements in its body do not have matching underlying types. Básicamente que estamos definiendo como retorno un tipo opaco pero estamos devolviendo dos tipos diferentes. En cambio, si devolvemos sólo un tipo, el error desaparece:


Recordemos que en Swift 5.1 también es posible omitir return cuando devolvemos una expresión simple.

SwiftUI

Empezamos hablando de SwiftUI así que vamos a ver los tipos opacos en acción con una ejemplo de lo que no se podría hacer debido a esta característica. Partimos del siguiente código:


Esto funciona a las mil maravillas pero quiero añadir una condición para que se muestre (o no) el saludo en más idiomas. Para ello tengo que agrupar los Text en un HStack.

Y aquí vemos que muestra el mismo error que antes porque una vez devuelvo un Text y otra un HStack y aunque ambos se conforman al protocolo View al tener que ser opaco el tipo devuelve, siempre tiene que coincidir.

Está claro que podemos hacer de forma sencilla un par de cambios y conseguir lo que queremos. Por ejemplo, esta solución si compilaría:


En este caso, HStack recibe uno o varios View y devuelve un tipo que se conforma también a View permitiendo cumplir la condición de los tipos opacos.

Para qué

No sé si es común o sólo me pasa a mi, pero una vez entendido un concepto, la siguiente pregunta es buscar la razón por la cuál existe. En este caso, los tipos opacos complementa la programación orientada a protocolos, y proporcionan más flexibilidad en casos en los que antes necesitábamos devolver tipos y no podríamos utilizar protocolos. Por otra parte, desconozco cómo está implementado SwiftUI por dentro, pero seguro que necesita esta característica para poder componer la interfaz, razón por la cuál aunque Swift es software libre, Apple forzó a que se implementase esta propuesta.

O así lo veo yo pero seguro que alguien puede aportar algo más, si es así, tenéis la caja de comentarios.

Comentarios

Entradas populares de este blog

Lenguajes, Frameworks, SDKs, churras y merinas en Swift

Hace unos días, alguien preguntaba en Twitter por recomendaciones sobre algún lenguaje de programación para iniciar su aprendizaje. Ni corto ni perezoso contesté: “Swift”. La respuesta me dejó bastantes sorprendido ya que dijo: “No, gracias pero Swift es Apple”. Algún día os contaré las mil y una bondades sobre Swift como lenguaje de programación, pero hoy quiero hablaros de la separación entre el propio lenguaje de programación y las diferentes librerías compatibles o basadas en ellos.

Primero el lenguaje Un lenguaje de programación es el conjunto de instrucciones, de palabras reservadas, la sintaxis incluyendo la puntuación y separación de instrucciones con las que podemos generar un programa que compilado o no, sea capaz de ejecutarse en una máquina. Seguro que la Wikipedia no dice lo mismo pero sí parecido y me gusta más mi definición.

Los lenguajes de programación pueden tener un creador o varios, particular o empresa, y pueden estar licenciados como software libre o ser propieda…

Desarrollo nativo con iOS

Hace varios años, la única opción para desarrollar una aplicación y que pudiera ejecutarse en varios sistemas, iOS y Android principalmente, era la plataforma Apache Cordova. Era bastante pesada ya que utilizaba contenedores web y costaba mover con los procesadores móviles de la época. Pero en la actualidad existen soluciones que generan código ya compilado, véase Xamarin o ReactNative, en base a un sólo desarrollo.


Partiendo de la premisa de que consideremos nativas las aplicaciones realizadas con las herramientas de desarrollo oficiales de Apple, vamos a analizar y sobretodo a comparar el desarrollo sobre estas plataformas intentando no entrar, aunque va a ser imposible, en opiniones personales.

Optimización y velocidad Como comentaba en las líneas anteriores, el principal escollo de las plataformas que utilizan contenedores web es el consumo de recursos. Para ejecutarse digamos que cada aplicación que tengamos abierta está utilizando un navegador web casi completo que por un lado …