ProgramaciónDesarrollador iOS Senior

Describe el mecanismo de generics en Swift. ¿Cómo garantizar la seguridad de tipo al trabajar con tipos genéricos? Proporcione ejemplos de restricciones de tipos genéricos.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Los generics (tipos genéricos) permiten definir funciones y tipos flexibles y reutilizables. Una característica clave de Swift es la preservación de la seguridad de tipo: el compilador verifica el trabajo con tipos específicos en tiempo de compilación. Los tipos genéricos se pueden restringir a través de condiciones where, herencia de protocolos y combinaciones de estos.

Ejemplo de código:

func swapValues<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } protocol Drawable { func draw() } func drawAll<T: Drawable>(_ items: [T]) { for item in items { item.draw() } } // Restricción por protocolo y condición where func compareValues<T: Equatable>(_ a: T, _ b: T) -> Bool { return a == b }

Pregunta capciosa.

¿Pueden las funciones genéricas actuar como funciones sobrecargadas? ¿Cómo elige el compilador la implementación necesaria?

Respuesta: Sí, las funciones genéricas pueden estar sobrecargadas con funciones normales y otras funciones genéricas. El compilador intenta elegir la implementación más específica. Ejemplo:

func printValue(_ value: Int) { print("Int: \(value)") } func printValue<T>(_ value: T) { print("Genérico: \(value)") } printValue(5) // Int: 5 printValue("Swift") // Genérico: Swift

Ejemplos de errores reales por desconocer matices del tema.


Historia

El equipo escribió una extensión genérica de un array para buscar un índice, olvidando restringir el tipo a través de Equatable. Esto llevó a un error de compilación al intentar aplicar la extensión a un array con elementos no Equatable.


Historia

En el proyecto intentaron implementar un caché de objetos genéricos sin restricción de tipo. Como resultado, al intentar hacer downcast en tiempo de ejecución surgieron crashes; el uso seguro real podría haberse logrado a través de protocolos con associated type y constraints.


Historia

Los desarrolladores implementaron una clase genérica, pero al heredar y sobrescribir olvidaron la necesidad de especificar el parámetro genérico completo del heredero. Como resultado, el código no se compilaba y se requería una reestructuración completa de la jerarquía de tipos.