¿Qué son los Tipos Opacos en Swift?

febrero 17, 2025

Los Tipos Opacos en Swift, también conocidos como Tipos de Retorno Opacos, son un concepto introducido en Swift 5.1. Simplifican el uso de Protocolos y Genéricos, especialmente con Protocolos que tienen Tipos Asociados. Este artículo explica qué son los tipos opacos y cómo usarlos.

El problema con Protocolos y Genéricos

Cuando una función devuelve un Protocolo con un Tipo Asociado, es difícil determinar el tipo de dato concreto del valor devuelto. Por ejemplo:

protocol P {
    associatedtype Value
    var value: Value { get } 
    init(value: Value) 
}

struct S1 : P { 
    var value: Int 
} 
struct S2: P { 
    var value: String 
}

// Error: No se puede inferir el tipo de retorno
// func foo() -> P { return S1() } 

Usar Genéricos también tiene limitaciones, ya que se debe especificar el tipo de dato para el parámetro o el valor de retorno de la función:

func foo<T: P>(value: T.Value) -> T { return T(value: value) }
let s1: S1 = foo(value: 10) 
let s2: S2 = foo(value: "ahihi")

La solución con Tipos Opacos

Los Tipos Opacos, declarados con la palabra clave some, permiten que una función devuelva un tipo de dato «oculto» que solo necesita cumplir con el Protocolo, sin necesidad de especificarlo.

func foo() -> some P { return S1(value: 11) }

En el ejemplo anterior, some P representa un tipo de dato concreto que cumple con el Protocolo P; el compilador lo inferirá automáticamente.

Sin embargo, un Tipo Opaco solo permite devolver un único tipo de dato en la misma función:

// Error: No se pueden devolver múltiples tipos de datos diferentes
// func bar(_ x: Int) -> some P {
//     if x > 10 { return S1(value: 12) } 
//     else { return S2(value: "ahihi") } 
// }

Tipos Opacos y PATs (Protocolos con Tipos Asociados)

Los Tipos Opacos son especialmente útiles al trabajar con PATs. Permiten usar PATs como tipo de retorno sin conocer el tipo de dato concreto, lo que hace el código más flexible y no lo limita a la versión de la biblioteca.

func giveMeACollection() -> some Collection { return [1, 2, 3] }
let collection = giveMeACollection()
print(collection.count) // 3

Tipos Opacos y tipos concretos

Cuando una función con un Tipo Opaco devuelve un tipo concreto, el compilador garantiza que las llamadas a esa función siempre devuelvan el mismo tipo.

func fooo() -> some Equatable { return 5 }
let f1 = fooo() 
let f2 = fooo()
print(f1 == f2) // true

Sin embargo, esto no se aplica a los PATs. Cada función con un Tipo Opaco y PATs devolverá un tipo de dato distinto, incluso si ambos cumplen con el mismo Protocolo.

Tipos Opacos y marcadores de posición genéricos

Combinar Tipos Opacos con marcadores de posición genéricos permite crear funciones versátiles con múltiples tipos de datos, sin necesidad de devolver un tipo concreto.

¿Por qué usar Tipos Opacos?

Los Tipos Opacos brindan flexibilidad al trabajar con Protocolos, especialmente con PATs. Ayudan a evitar la necesidad de especificar el tipo de dato concreto, reducen la dependencia de la versión de la biblioteca y aumentan la reutilización del código.

Tipos Opacos en SwiftUI

Los Tipos Opacos se utilizan ampliamente en SwiftUI. La propiedad body del Protocolo View tiene el tipo some View, lo que permite devolver cualquier tipo de dato que cumpla con el Protocolo View, simplificando la construcción de la interfaz de usuario. El uso de some View evita tipos de datos complejos cuando una Vista tiene varios niveles anidados.

Leave A Comment

Categorías

Recent Posts

Create your account