← Swift EspañolChapter 11 of 13

Extensiones y Genericos

## Objetivos de Aprendizaje - Extender tipos existentes con extensiones - Usar delegacion de protocolos - Dominar conceptos basicos de genericos - Escribir funciones y tipos genericos ## Extensiones ### Agregar Funcionalidad ```swift extension Int { func alCuadrado() -> Int { return self * self } } let numero = 5 print(numero.alCuadrado()) // 25 ``` ### Agregar Propiedades Calculadas ```swift extension Double { var kmAMillas: Double { return self * 0.621371 } var millasAKm: Double { return self * 1.60934 } } let distancia = 10.0 print("\(distancia) km = \(distancia.kmAMillas) millas") ``` ### Agregar Inicializadores ```swift struct Punto { var x: Int var y: Int } extension Punto { init(xy: Int) { self.init(x: xy, y: xy) } } let origen = Punto(xy: 0) // Punto(x: 0, y: 0) ``` ### Agregar Metodos ```swift extension Array { func promedio() -> Double? { guard !isEmpty else { return nil } return Double(reduce(0, +)) / Double(count) } } let puntuaciones = [90, 85, 92, 88] print(puntuaciones.promedio()) // Optional(88.75) ``` ## Conformidad a Protocolos ### Extender para Conformar ```swift protocol Imprimible { func descripcion() -> String } extension Int: Imprimible { func descripcion() -> String { return "Numero: \(self)" } } print(42.descripcion()) // "Numero: 42" ``` ### Agregar Requisitos de Protocolo ```swift extension Array where Element: Equatable { func contiene(_ elemento: Element) -> Bool { for item in self { if item == elemento { return true } } return false } } let nums = [1, 2, 3, 4, 5] print(nums.contiene(3)) // true print(nums.contiene(10)) // false ``` ## Delegacion de Protocolos ### Definir Protocolos ```swift protocol ManejadorDatosDelegate: AnyObject { func datosRecibidos(_ datos: Data) func falloConError(_ error: Error) } class ManejadorDatos { weak var delegate: ManejadorDatosDelegate? func obtenerDatos() { // ... obtener datos let datos = Data() delegate?.datosRecibidos(datos) } } ``` ### Implementar Delegate ```swift class ControladorVista: ManejadorDatosDelegate { let manejador = ManejadorDatos() init() { manejador.delegate = self } func datosRecibidos(_ datos: Data) { print("Recibidos \(datos.count) bytes") } func falloConError(_ error: Error) { print("Error: \(error)") } } ``` ### Beneficios del Patron Delegate - Acoplamiento flexible - Flexibilidad - Multiples delegates posibles - Separacion clara de responsabilidades ## Genericos ### Por Que Genericos? ```swift // Sin genericos - codigo repetido func intercambiarEnteros(_ a: inout Int, _ b: inout Int) { let temp = a a = b b = temp } func intercambiarCadenas(_ a: inout String, _ b: inout String) { let temp = a a = b b = temp } // Con genericos - una funcion func intercambiar(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } var x = 1, y = 2 intercambiar(&x, &y) var s1 = "Hola", s2 = "Mundo" intercambiar(&s1, &s2) ``` ## Funciones Genericas ### Sintaxis ```swift func identidad(_ valor: T) -> T { return valor } let num = identidad(42) // Inferido como Int let str = identidad("hola") // Inferido como String ``` ### Multiples Parametros de Tipo ```swift func combinar(_ a: A, _ b: B) -> (A, B) { return (a, b) } combinar(1, "uno") // (1, "uno") ``` ### Restricciones de Tipo ```swift // Restriccion Comparable func maximo(_ a: T, _ b: T) -> T { return a > b ? a : b } maximo(5, 10) // 10 maximo("manzana", "banana") // "banana" ``` ## Tipos Genericos ### Struct Generico ```swift struct Pila { var elementos: [Elemento] = [] mutating func apilar(_ item: Elemento) { elementos.append(item) } mutating func desapilar() -> Elemento? { return elementos.popLast() } func ver() -> Elemento? { return elementos.last } } var pilaInt = Pila() pilaInt.apilar(1) pilaInt.apilar(2) print(pilaInt.desapilar()) // Optional(2) var pilaCadena = Pila() pilaCadena.apilar("Hola") pilaCadena.apilar("Mundo") ``` ### Clase Generica ```swift class Cola { private var elementos: [Elemento] = [] func encolar(_ item: Elemento) { elementos.append(item) } func desencolar() -> Elemento? { return elementos.removeFirst() } func ver() -> Elemento? { return elementos.first } } ``` ### Enum Generico ```swift enum Resultado { case exito(Valor) case fracaso(Error) } let exito: Resultado = .exito(42) let fracaso: Resultado = .fracaso("Ocurrio un error") ``` ## Restricciones de Tipo en Extensiones ### Sintaxis de Restricciones de Tipo ```swift func encontrarIndice(de valor: T, en arreglo: [T]) -> Int? { for (indice, item) in arreglo.enumerated() { if item == valor { return indice } } return nil } ``` ### Multiples Restricciones ```swift func encontrarCadena(en coleccion: T) -> T.Element? where T.Element == String { return coleccion.first(where: { !$0.isEmpty }) } ``` ### Restricciones de Protocolo ```swift func procesar(valores: [T]) -> T? { return valores.filter { $0 > 0 }.max() } procesar(valores: [1, -2, 3, 0]) // Optional(3) ``` ## Extensiones con Genericos ### Extender Tipos Genericos ```swift extension Pila where Elemento: Comparable { func ordenado() -> [Elemento] { return elementos.ordenado() } } var pila = Pila() pila.apilar(3) pila.apilar(1) pila.apilar(2) print(pila.ordenado()) // [1, 2, 3] ``` ### Extension con Self ```swift extension Numeric { func alCuadrado() -> Self { return self * self } } let num: Int = 5 print(num.alCuadrado()) // 25 let dbl: Double = 3.0 print(dbl.alCuadrado()) // 9.0 ``` ## Tipos Asociados ### Protocolo con Tipo Asociado ```swift protocol Contenedor { associatedtype Elemento mutating func append(_ item: Elemento) var cantidad: Int { get } subscript(i: Int) -> Elemento { get } } ``` ### Struct Generico Conformando ```swift struct ContenedorInt: Contenedor { private var elementos: [Int] = [] mutating func append(_ item: Int) { elementos.append(item) } var cantidad: Int { elementos.cantidad } subscript(i: Int) -> Int { return elementos[i] } } ``` ## Tipos Opacos ### Palabra Clave some ```swift protocol Figura { func dibujar() } struct Circulo: Figura { func dibujar() { print("Circulo") } } struct Cuadrado: Figura { func dibujar() { print("Cuadrado") } } func hacerFigura() -> some Figura { return Circulo() } let figura = hacerFigura() figura.dibujar() // Circulo ``` ### Casos de Uso ```swift // SwiftUI usa tipos de retorno opacos func hacerVistaContenido() -> some Vista { Texto("Hola") } ``` ## Resumen - Las extensiones agregan funcionalidad a tipos existentes - Propiedades calculadas, metodos, inicializadores pueden ser agregados - Usar clausula `where` para conformidad condicional - La delegacion separa preocupaciones via protocolos - Los genericos permiten codigo reutilizable seguro para tipos - Restricciones de tipo: `` - Funciones genericas: `func identidad(_ x: T) -> T` - Tipos genericos: `struct Pila` - Tipos asociados para protocolos genericos - `some` para tipos de retorno opacos

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →