Historia de la pregunta:
Los tipos opacos (some) aparecieron con Swift 5.1 y abrieron una nueva forma de abstraer el valor de retorno de una función o propiedad, donde el tipo es conocido por el compilador, pero está oculto al usuario. Esta es una alternativa a los existenciales de protocolo (any Protocol), pero con una fuerte conexión a un tipo específico dentro de la función.
Problema: Cuando una función devuelve un protocolo con associatedtype (por ejemplo, Sequence), no se puede escribir directamente:
func makeNumberSequence() -> Sequence { ... } // error
Los existenciales de protocolo permiten devolver cualquier implementación, pero no garantizan el mismo tipo en cada llamada:
func foo() -> any View { ... }
Esto conduce a imprevisibilidad y baja seguridad de tipo.
Solución: Usar un tipo de resultado opaco:
func makeNumbers() -> some Sequence { [1, 2, 3] }
Ahora el compilador sabe exactamente el tipo de retorno real, pero está oculto externamente. Esto proporciona optimizaciones de rendimiento, seguridad, permite usar DSL de SwiftUI, facilita el intercambio de tipos entre módulos.
Características clave:
¿Pueden los tipos opacos usarse para almacenar valores (como propiedades de clase)?
No. Los tipos opacos solo se aplican a los valores de retorno de funciones o propiedades calculadas. Para almacenar un valor o un array de valores, se utilizan existenciales (any Protocol).
¿Pueden diferentes ramas de una función devolver diferentes tipos con some?
No. El compilador requiere que ambas (o todas) las ramas devuelvan el mismo tipo específico, de lo contrario, habrá un error:
func foo(flag: Bool) -> some Sequence { if flag { return [1, 2, 3] } else { return ["a", "b", "c"] // error } }
¿Se puede usar some para identificar el tipo de retorno entre varias funciones?
No. Cada función con some devuelve su propio tipo oculto único, incluso si en realidad es el mismo array. No se puede usar el resultado de una función como parámetro en otra si ambas utilizan some con diferentes protocolos o diferentes tipos ocultos.
En el proyecto todo se devuelve a través de any Protocol, las colecciones pierden su tipificación, aparecen errores al usar downcast, se ralentiza la optimización en tiempo de compilación.
Ventajas:
Desventajas:
En el diseño de SwiftUI, los componentes devuelven some View, cada módulo define claramente su tipo interno. El tamaño del bundle se reduce, la compilación se acelera.
Ventajas:
Desventajas: