Con Swift 5.3, los desarrolladores se beneficiarán de nuevas y potentes características como cláusulas de captura de múltiples patrones y múltiples cierres finales, que agilizan el desarrollo. Asimismo, el Swift Package Manager evoluciona con cambios sustanciales.
1.Capacidad de capturar varias cláusulas de error en un solo bloque catch: SE-0276
enum ErrorDeTemperatura: Error {
case demasiadoCaliente, ErrorDeTemperatura
}
do {
let estadoDelNucleo = try verificarNucleoOperativo()
print("Estado del núcleo: \(estadoDelNucleo)")
} catch ErrorDeTemperatura.demasiadoCaliente, ErrorDeTemperatura.demasiadoFrio {
print("Hemos podido reunir varias clases de error en una sola clausula catch")
} catch {
print("Se produjo un error desconocido.")
}
2. Múltiples cierres finales (trailing closures):SE-0279
Ahora podemos llamar una función con varios cierres finales. El único requisito es que cada cierre después del primero debe especificar una etiqueta. Esto es especialmente útil en el contexto de SwiftUI.
Por ejemplo,consideremos una función que dado dos números ejecuta una operación de suma y otra de resta sobre los mismos. Los resultados se devuelven en dos closures. Observe que ahora podemos llamar a los dos closures:
func ExecuteMat(opA : Int, opB : Int, suma : (Int)->Void, resta : (Int)->Void )->Void{
suma(opA + opB)
resta(opA - opB)
}
ExecuteMat(opA: 10, opB: 5){ sumaResult in
print(sumaResult) //imprime 15
}
resta: { restaResult in
print(restaResult)//imprime 5
}
3. Las enumeraciones adquiren conformidad con el protocolo Comparable: SE-0266
Para aquellas enumeraciones cuyos casos de uso siguen un orden semántico obvio, la conformidad con Comparable permite realizar comparaciones entre sus casos:
enum SchoolGrades : Comparable {
case F
case E
case D
case C
case B
case A
}
print(SchoolGrades.D > SchoolGrades.E) //true: la letra D esta primero que la E, por tanto se considera mayor que E
4. self ya no es necesario en muchos lugares:SE-0269
Antes de Swift 5.3 era necesario utilizar self dentro de los cierres para hacer explícita la referencia al contexto externo. Por ejemplo:
struct view : View {
var body: some View {
VStack{
Button{
//action
}label: {
Text(self.saludo(nombre: "Yorj")) //acceso explicito al contexto fuera del cierre
}
}
}
func saludo(nombre: String)->String{
return "Hola! \(nombre)"
}
}
Gracias a SE-0269, simplemente podemos omitir el uso de self. Este cambio mejora la legibilidad dentro de SwiftUI o Combine.
5. Nuevo atributo @main para establecer el punto de entrada: SE-0281
Se ha introducido un nuevo atributo @main que permite identificar el punto de entrada del programa cuando este inicia. Esto es muy útil cuando se desarrolla programas de líneas de comandos.
Por ejemplo, anteriormente, al crear un programa de teminal se necesitaba crear un archivo llamado main.swift como punto de entrada para iniciar nuestro código:
struct MyApp {
func run() {
print("en ejecución")
}
}
let app = MyApp()
app.run()
Este antiguo enfoque siendo siendo válido, pero ahora tenemos la libertad de marcar con @Main una estructura o clase que contenga un método estático main para convertirlo en punto de entrada.
@main
struct MyNewApp {
static func main() {
print("Running!")
}
}
Swift identificará MyNewApp como el punto de entrada y iniciará el programa ejecutando el método main().
Existen ciertas reglas en el uso del atributo @main:
- No es posible usar el atributo @main en un programa que ya contenga un archivo main.swift
- No es posible utilizar más de un atributo @main
- Solo se aplicará a una clase base; no es posible heredarlo
6. Cláusula Where en declaraciones contextualmente genéricas: SE-0267
Swift 5.3 introdujo la posibilidad de utilizar cláusulas where en funciones dentro de tipos genéricos y extensiones.
Por ejemplo, consideremos una estructura que representa una coleccion de elementos:
struct Pila{
var array : [Element]
mutating func pust(_ obj: Element){
array.append(obj)
}
mutating func pop()->Element?{
self.array.popLast()
}
}
Ahora podemos declarar una función que devuelva los elementos ordenados pero solo si estos conforman Comparable:
extension Pila{
func sorted()->[Element] where Element : Comparable{
return array.sorted()
}
}
7. Los casos de enum ahora pueden ajustarse a protocolos: SE-0280
Esto quiere decir que podemos tener un case de enum que coincida con un requisito de protocolo. Veamos un ejemplo ilustrativo para que se comprenda mejor:
protocol Def {
static var valueDef: Self { get }
}
enum Padding: Def {
case pixels(Int)
case cm(Int)
case valueDef //valor que corresponde al requisito del protocolo
}
8. Se ha redefinido la semántica de didSet: SE-0268
El captador de propiedad didSet se optimiza para que no recupere el valor anterior si no es necesario. Esta mejora se traduce en un mejor rendimiento del código detras de escena. Si necesita recuperar el valor anterior solo debes hacer referencia al mismo dentro del observador de propiedades.
Si tienes un código anterior a esta versión de Swift y dependes del comportamniento anterior, solo tienes que hacer un pequeño ajuste:
didSet {
_ = oldValue
}
9. Nuevo tipo: Float16: SE-0277
Swift 5.3 incorpora un nuevo tipo Float16 de punto flotante y media presición utilizado de manera regular en operaciones sobre gráficos y aprendizaje automático. Este viene a ser parte de la familia de tipos similares:
let primero: Float16 = 5
let segundo: Float32 = 11
let tercero: Float64 = 7
let cuarto : Float80 = 13
10. Swift Package Manager (SPM) puede manejar dependencias binarias, ficheros y más…
El administrador de paquetes de Swift adquiere nuevas capacidades y ahora puede manejar varios tipos de archivos y recursos:
- Recursos: Ahora el SPM puede almacenar recursos como imágines, JSON, etc. Esto agrega una nuevo metodode acceso a estos recursos en tiempo de ejecución con Bundle.module. También permite almacenar “recursos localizados” para permitir versiones localizadas de recursos, por ejemplos imágines en otros idiomas. Estos recursos son de acceso seguro de modo que podemos establecer una ruta única de acceso a los mismos.
- Dependencias binarias: SPM ahora puede manejar dependencias binarias junto con la correspondiente compatibilidad con el código fuente. Esto significa que ahora se puede integrar SDK cerrados como firebase a través de SPM.
- Destinos dependientes de la plataforma. Ahora es posible configurar destinos para que tengan dependencias solo de la plataforma y configuraciones específicas. Por ejemplos podemos decirle que necesitamos algunos framework adicionales al compilar para linux. O que deberíamos incorporar algún código de depuración para pruebas locales.
Conclusión:
Swift 5.3 representa un avanze importante del lenguaje al incorporar nuevas características como mútiples cierres finales, el manejo de varios errores en un único bloque catch, un nuevo tipo de Float y avanzadas características en el SPM. estas novedades junto con correcciones importantes y mejoramiento del desempeño hacen del lenguaje Swift una mejor herramienta para el desarrollo de aplicaciones.
Si te ha gustado este contenido puedes escribirme un comentario. Gracias por leer. Feliz codificación!