Novedades en Swift 6

Novedades en Swift 6

Swift 6 , presentado en la WWDC 2024, es un salto cuántico en el desarrollo de software, ofreciendo un conjunto de herramientas y características que empoderan a los desarrolladores para crear aplicaciones más seguras, rápidas y escalables. Con un enfoque en la seguridad, la concurrencia y la productividad, Swift 6 simplifica la escritura de código complejo y abre nuevas posibilidades para la creación de aplicaciones innovadoras en todo el ecosistema de Apple y más allá.

No se asombre de que con Swift 6 su código emita nuevos errores y advertencias; sobre todo relacionados con la concurrencia. Esto no quiere decir que este incorrecto del todo sino que ahora el compilador de Swift 6 es más preciso y robusto y detecta condiciones potencialmente peligrosas en la lógica de su proyecto. Aproveche esta nueva capacidad para detectar tempranamente problemas que estaban ocultos.

Y ahora haremos un repaso sobre las principales características que sobresalen en Swift 6, a propósito de su 10.º Aniverario 🎉! 

1. Verificación completa de concurrencia

En versiones anteriores a Swift 6 era opcional la activación del chequeo estricto de la concurrencia. Esto permitió a los desarrolladores una migración suave. Ahora esta verificación esta activada completamente de manera predeterminada. 

Swift 6 mejora drásticamente la comprobación de la concurrencia. Además, según el equipo de Swift se eliminan muchas advertencias de falsos psitivos sobre condiciones de carrera que estaban presentes en la versión 5.10. 

También introduce cambios específicos para que la adopción de la concurrencia sea mucho más fácil. Por ejemplo, Swift 6 define regiones de aislamiento que permiten al compilador determinar de manera concluyente  partes en el código que pueden ejecutarse con seguridad en paralelo.

Te animo a que leas sobre este tema importante. Un buen punto de partida es este blog

2. count(where:) : SE-0220

Se introduce una nueva función de orden superior count(where: ) que ejecuta el equivalente a filter() y count en una sola pasada. Esto evita la creación de un nuevo arreglo que se descarta inmediatamente, proveyendo de una solución más clara y concisa a muchos problemas comunes.

Veamos un ejemplo:

				
					
let values: [Int] = [14,2,8,17]

//Swift 5.x
let dd = values.filter{$0 <= 10}.count
print(dd)

//Swift 6:
let dd = values.count{$0 <= 10}
print(dd)
				
			

Este método esta disponible para todos los tipos que cumplen con Sequence.

Curiosidad: Originalmente esta función se planeó para Swift 5.0 en 2019, pero se retiró en ese momento por razones de rendimiento.

3. Throws tipificados: SE-0413

Se ha introducido la capacidad de especificar los errores específicos que una función puede lanzar, conocido como “typed throws” o errores tipados o tipificados. Esto resuelve un problema con los errores en Swift: Antes se necesitaba de una cláusula cacth general aún cuando habíamos detectado todos los errores posibles.

Para más info puede consultar este post.

4. Iteración de paquetes: SE-0408

Ahora es posible la iteración de paquetes, que agrega la capacidad de recorrer la función de paquetes de parámetros introducida en Swift 5.9.

				
					func == <each Element: Equatable>(lhs: (repeat each Element), rhs: (repeat each Element)) -> Bool {
    for (left, right) in repeat (each lhs, each rhs) {
        guard left == right else { return false }
    }
    return true
}
				
			

Esto significa que anterior a Swift 6 se habia agregado la comparación de tuplas de hasta 6 elementos en los paquetes de parámetros. Ahora, gracias SE-0408 esta restricción se elimina.

5. Nuevas funciones para manipular grupos de elementos no contiguos en colecciones: SE-0270

Este cambio esta basado en un nuevo tipo llamado RangeSet. Se han actualizado muchas APIs de Swift a RangeSet.

El siguiente ejemplo, tomado de este post de Paul Hudson, resulta útil:

Podríamos crear una matriz de estudiantes con resultados de exámenes como esta:

				
					struct ExamResult {
    var student: String
    var score: Int
}

let results = [
    ExamResult(student: "Eric Effiong", score: 95),
    ExamResult(student: "Maeve Wiley", score: 70),
    ExamResult(student: "Otis Milburn", score: 100)
]
				
			

Podemos obtener un RangeSet que contenga los índices de todos los estudiantes que obtienen una puntuación de 85% o más de la siguiente manera:

				
					let topResults = results.indices { student in
    student.score >= 85
}
				
			

Y si quisiéramos tener acceso a esos estudiantes, podemos usar un nuevo  subíndice Collection:

				
					for result in results[topResults] {
    print("\(result.student) scored \(result.score)%")
}
/*
Este subíndice devuelve otro tipo nuevo llamado DiscontiguousSlice, que es similar a Sliceen que, por razones de rendimiento, se refiere a elementos almacenados en una colección diferente, excepto que los índices son discontinuos , lo que significa que no son necesariamente adyacentes en la colección.

La parte "set" del nombre está ahí porque RangeSetadmite una variedad de funciones que provienen del SetAlgebraprotocolo, incluidas union(), intersection()y isSuperset(of:). Esto también significa que al insertar un rango en otro se fusionarán los rangos superpuestos en lugar de crear duplicados.
*/
				
			

6. Modificadores de nivel de acceso en las declaraciones de importación: SE-0409

Ser agrega la capacidad de marcar declaraciones de importación con modificadores de nivel de  acceso como:

  • private import <SomeLibrary>
  • internal import <SomeLibrary>
  • public import <SomeLibrary>

Para más información puede consultar este post.

7. Actualización de tipos no copiables (noncopyables).

Los tipos no copiables fueron introducidos en Swift 5.9 y en esta versión han recibido una serie de actualizaciones:

  • Cada tipo, enumeración, parámetro genérico se ajusta por defecto a un protocolo: Copyable, a menos que opte por declararlo explícitamente como ~Copyable.
  • Los genéricos admiten tipos no copiables
  • Los tipos no copiables ahora pueden cumplir protocolos, pero solo si estos están marcados como ~Copyable.
  • Se agrega consumo parcial de valores no copiables

Estas mejoras ayudan a que los tipos no copiables funcionen de manera más natural en Swift.

8. Nuevos tipos enteros de 128 bits: SE-0425

Dos nuevos tipos en Swift: Int128 y UInt128 Para l manejo de números grandes.

9. Nueva sintaxis para restricciones genéricas.

Swift 6 introduce una nueva sintaxis para restricciones genéricas utilizando la palabra clave “where” para especificar las condiciones que deben cumplir los prámetros genéricos:

				
					func merge<T: Comparable>(arrays: [T]) -> [T] where T: AdditiveArithmetic {
// Merge and sort arrays
}
				
			

10. Bitwise copiable: SE-0426 

Se incorpora un nuevo protocolo BitwiseCopyable cuyo único propósito es permitirle al compilador crear un código más optimizado para los tipos conformes.

Swift aplicará esta conformidad a la mayoria de las estructuras y enumeraciones, siempre que contengan elementos que se puedan copiar bit a bit.

Conclusion

Swift 6 nos brinda una programación más robusta y consistente. Las peligrosas condiciones de carrera están cubiertas al menos en los casos de uso conocido y muchas mejoras y optimizaciones permiten a los desarrolladores crear un código más limpio, escalable y seguro.

Migración a Swift6: La comunidad y el equipo de Swift ha preparado un tutorial que le asiste en la migración de su código. Lo puede consultar aquí.

Gracias por leer, si te ha gustado el contenido puede dejarme un comentario. Feliz codificación!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio