Genéricos, associatedtype, some y any en Swift
Guía de restricciones genéricas, associatedtype, tipos opacos, existenciales y sus trade-offs.
Para qué sirven los genéricos
Reutilizan funciones y tipos sin perder relaciones de tipos en compilación. Una restricción como Equatable expresa el requisito real de comparar valores. Evita parámetros genéricos si no simplifican una necesidad concreta.
func firstMatch<T: Equatable>(_ items: [T], value: T) -> T? {
items.first { $0 == value }
}
let answer = firstMatch([1, 3, 5], value: 3)associatedtype
Declara una relación de tipos en un protocolo; el tipo concreto lo fija cada conformante. Se usa en repositorios, secuencias y abstractions donde la salida está ligada a la implementación.
protocol Repository {
associatedtype Model
func load() async throws -> [Model]
}
struct Account { let id: String }
struct AccountRepository: Repository {
func load() async throws -> [Account] { [Account(id: "1")] }
}
func loadAll<R: Repository>(from repo: R) async throws -> [R.Model] {
try await repo.load()
}some frente a any
some en un parámetro es una abreviatura genérica. some P como retorno oculta un tipo concreto estable elegido por la función. any P guarda dinámicamente cualquier conformante y permite inyección flexible, pero introduce borrado de tipo e impide algunas operaciones que dependen de Self o associatedtype.
protocol Greeter {
func greet() -> String
}
struct EnglishGreeter: Greeter {
func greet() -> String { "Hello" }
}
func makeGreeter() -> some Greeter { EnglishGreeter() }
func speak(using greeter: any Greeter) -> String {
greeter.greet()
}| Sintaxis | Quién decide el tipo | Compromiso |
|---|---|---|
| T: P / parámetro some P | El llamador | Conserva relaciones entre tipos |
| Retorno some P | La implementación | Un tipo concreto oculto |
| Valor any P | En ejecución | Flexible, posible boxing |
| associatedtype | Cada conformante | Relación explícita de tipos |
Preguntas trampa
No puedes devolver tipos concretos distintos de varias ramas de una función some P sin otra abstracción. any P no equivale a restricción genérica. En APIs simples, una interfaz concreta puede ser más legible que un diseño excesivamente genérico.
Notas personales de estudio. Verifica los matices según la versión de Swift/iOS y la documentación oficial.