Swift 5.0. Que hay de nuevo

Swift 5: el lanzamiento tan esperado, que incluye varias docenas de mejoras y correcciones. Pero el objetivo principal del lanzamiento de Swift 5.0 era lograr la estabilidad ABI. En este artículo, aprenderá qué es ABI y qué estable ABI le dará a los desarrolladores de iOS / macOS. También analizaremos varias características nuevas de Swift 5.



Estabilidad ABI


ABI es una interfaz de aplicación binaria. Un ABI puede considerarse como un conjunto de reglas que permiten que un enlazador combine módulos de componentes compilados.


En consecuencia, lo siguiente se describe en ABI.


  1. La forma en que se llama el código desde diferentes módulos, incluidos los del sistema.
  2. El formato para pasar argumentos y obtener el valor de retorno de las funciones.
  3. Algoritmos de diseño de datos RAM.
  4. Gestión de la memoria, ARC.
  5. Sistema de tipos, genéricos.

Swift 5, junto con ABI estable, proporciona compatibilidad binaria para aplicaciones. La compatibilidad binaria para aplicaciones iOS / macOS significa que las aplicaciones compiladas serán compatibles en tiempo de ejecución con las bibliotecas del sistema compiladas por versiones anteriores o posteriores del lenguaje. Por ejemplo, una aplicación compilada con Swift 5.0 será compatible con las bibliotecas estándar compiladas con Swift 5.1 o Swift 6.0.


A partir de iOS 12.2 y macOS 10.14.4, los sistemas operativos de Apple contendrán todo lo que necesita para ejecutar aplicaciones rápidas. Esto significa que las aplicaciones escritas en Swift 5 y versiones posteriores no contendrán tiempo de ejecución y una biblioteca de idiomas estándar. Por lo tanto, las aplicaciones escritas en Swift 5 pesarán entre 3 y 10 megabytes menos.


Es importante tener en cuenta que, además de la estabilidad ABI, también existe la estabilidad del Módulo. Si la estabilidad ABI permite combinar diferentes versiones de un swift en tiempo de ejecución, la estabilidad del módulo es responsable de cómo se compilan los marcos binarios escritos en diferentes versiones del lenguaje. La estabilidad del módulo aparecerá en Swift 5.1. Y luego los desarrolladores podrán distribuir sus marcos no solo con código fuente abierto, sino también en forma compilada.


Ventajas de la estabilidad ABI.


  1. Las aplicaciones pesarán menos.
  2. Acelerar el inicio y el rendimiento de la aplicación.
  3. En teoría, Apple podría escribir nuevos marcos completamente en Swift.

Contras ABI estabilidad.


Los desarrolladores tendrán que considerar la falta de cualquier funcionalidad nueva en las versiones anteriores de la biblioteca estándar. Por ejemplo, si Swift 5.1 con cualquier clase / función nueva en la biblioteca estándar está construida en iOS 13, entonces con el soporte en la aplicación iOS 12.2, los desarrolladores no podrán usarlas. (Deberá insertar las comprobaciones #available (...) de la misma manera que lo hacemos ahora para Foundation, UIKit y otras bibliotecas de plataformas).


Tipo de resultado en la biblioteca estándar


La biblioteca estándar tiene una forma conveniente de transmitir y manejar errores en la API asincrónica. También puede usar este tipo si, por alguna razón, el manejo de errores estándar a través de try / catch no nos conviene.


El tipo de resultado se implementa a través de enum con dos casos: éxito y fracaso:


public enum Result<Success, Failure> where Failure: Error { case success(Success) case failure(Failure) ... } 

De hecho, este enfoque no es nuevo para los desarrolladores de Swift. Desde la primera versión de Swift, muchos desarrolladores han utilizado un enfoque similar. Pero ahora, cuando el Resultado ha aparecido en la biblioteca estándar, esto simplificará la interacción con el código de las bibliotecas externas.


Un ejemplo del uso del servicio de descarga de artículos:


 struct Article { let title: String } class ArticleService { func fetchArticle(id: Int64, completion: @escaping (Result<Article, Error>) -> Void) { //    // ... completion(.success(Article(title: "Swift 5.0.  ?"))) } } 

Y aquí hay un ejemplo de procesamiento del resultado. Como Result es solo una enumeración, podemos procesar todos sus estados con un interruptor:


 articleService.fetchArticle(id: 42) { result in switch result { case .success(let article): print("Success: \(article)") case .failure(let error): print("Failure: \(error)") } } 

Cuerdas crudas


En Swift 5, agregaron las llamadas cadenas sin formato, en las que las comillas y la barra invertida se interpretan exactamente como caracteres, y no es necesario usar un carácter de escape para usarlas en un literal. Para escribir un literal para dicha cadena, debe agregar el carácter # a comillas dobles en los bordes.


Un ejemplo de uso de comillas:


 // swift 4.2 print("    \"\"   .") print("     ,    \\n") // swift 5 print(#" ""      "#) print(#"     ,    \n"#) 

Esta característica es especialmente útil al escribir expresiones regulares:


 // swift 4.2 let regex = "^\\(*\\d{3}\\)*( |-)*\\d{3}( |-)*\\d{4}$" // swift 5 let regex = #"^\(*\d{3}\)*( |-)*\d{3}( |-)*\d{4}$"# 

Para interpolar líneas después de la barra diagonal inversa, agregue el carácter #:


 // swift 4.2 let string = "   \(variable)" // swift 5 let string = #"   \#(variable)"# 

Puedes leer más en esta oración .


Interpolación de línea actualizada


Mediante la interpolación de cadenas, podemos agregar el valor de una variable o el resultado de una expresión a un literal de cadena. Comenzando con la quinta versión del lenguaje, se hizo posible expandir la forma en que nuestras expresiones se agregan a la línea final.
En general, solo escriba una extensión en la estructura DefaultStringInterpolation y agregue un método llamado appendInterpolation. Por ejemplo, si queremos agregar un precio en forma formateada a una cadena:


 extension DefaultStringInterpolation { mutating func appendInterpolation(price: Decimal) { let formatter = NumberFormatter() formatter.numberStyle = .currency if let string = formatter.string(from: price as NSDecimalNumber) { appendLiteral(string) } else { appendLiteral(price.description) } } } print("Price of item: \(price: 9.99)") // Price of item: $9.99 

Es importante tener en cuenta que, de hecho, la construcción (precio: 9,99) en la cadena que utiliza el compilador se transformó en una llamada al método appendInterpolation (precio: decimal).
También en los métodos appendInterpolation podemos agregar un número ilimitado de argumentos, tanto con nombre como sin nombre, con o sin valores predeterminados.


Puedes leer más en esta oración .


Comprobando la multiplicidad de números


El método para verificar la multiplicidad es múltiple (de :) se ha agregado a los tipos numéricos en la biblioteca estándar. Sí, aún podemos usar el operador para tomar el resto del% de división. Pero parece que isMultiple (of :) parece más visual.


 let interger = 42 if interger.isMultiple(of: 3) { print(" ") } else { print("  ") } 

Método CompactMapValues ​​en Diccionario


El método compactMapValues ​​le permite convertir valores de diccionario, así como filtrarlos si la conversión en sí misma devuelve nulo.


Por ejemplo, asignando claves de cadena a un tipo de URL:


 let dict = [ "site": "https://www.site.ru/path/to/web/site/page", "other site": "invalid url" ] let mappedDict: [String: URL] = dict.compactMapValues { URL(string: $0) } print(mappedDict) // ["site": https://www.site.ru/path/to/web/site/page] 

El segundo par clave / valor se eliminó después de la asignación, ya que la cadena no es una URL válida.


Intenta cambiar el comportamiento?


En Swift 4.2 usando la construcción try? puede obtener fácilmente un tipo opcional con varios niveles de anidamiento. En la mayoría de los casos, esto no es lo que el desarrollador espera. Por esta razón, en Swift 5 intente? Obtuve un comportamiento similar al encadenamiento opcional c. Es decir, con una combinación de prueba? con encadenamiento opcional o conversión opcional, el resultado de la expresión será opcional con un nivel de anidamiento.


Probar ejemplo? junto con como?:


 // Swift 4.2 let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] //  jsonDict - [String: Any]?? // Swift 5 let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] //  jsonDict - [String: Any]? 

Probar ejemplo? junto con el método de objeto opcional:


 // Swift 4.2 let article = try? storage?.getArticle() //  article - Article?? //  if let first = article, let second = first { first //  Article? second //  Article } //   if case let value?? = article { value //  Article } // Swift 5 let article = try? storage?.getArticle() //  article - Article? //  if let value = article { value //  Article } 

Puedes leer más en esta oración .


Atributo @DynamicCallable


El nuevo atributo @dynamicCallable le permite marcar el tipo como "invocable". Esto significa que podemos llamar al tipo como un método normal.
Si marcamos el tipo como @dynamicCallable, entonces debemos implementar uno (o ambos) de los métodos:


 func dynamicallyCall(withArguments: <#Arguments#>) -> <#R1#> func dynamicallyCall(withKeywordArguments: <#KeywordArguments#>) -> <#R2#> 

El tipo Argumentos debe admitir el protocolo ExpressibleByArrayLiteral, el tipo KeywordArguments debe admitir el protocolo ExpressibleByDictionaryLiteral, y R1 y R2 pueden ser de cualquier tipo.


Por ejemplo, la estructura de la suma. Cuando lo llama, puede transferir cualquier número de números y obtener su suma:


 @dynamicCallable struct Sum { func dynamicallyCall(withArguments args: [Int]) -> Int { return args.reduce(0, +) } } let sum = Sum() let result = sum(1, 2, 3, 4) print(result) // 10 

De hecho, el compilador convierte sum (1, 2, 3, 4) en una llamada a sum.dynamicallyCall (withArguments: [1, 2, 3, 4]). De manera similar para el método dynamicallyCall (withKeywordArguments :).


Esta característica le permite agregar la interacción del código Swift con varios lenguajes de programación dinámicos, por ejemplo, Python o JavaScript.


Puedes leer más en esta oración .


Menos soporte del operador en la versión del compilador y las directivas de verificación de idioma


Comenzando con la quinta versión de Swift, puede usar el operador "menos" al verificar la versión del compilador en el código:


 // Swift 4.2 #if !swift(>=5) //        4.2   #endif // Swift 5 #if swift(<5) //        4.2   #endif 

Conclusión


Estas no son todas las características y mejoras que aparecieron en Swift 5. En total, se aceptaron 28 propuestas de la comunidad, que también incluían mejorar el rendimiento de la línea, mejorar el Swift Package Manager y la biblioteca estándar. Puede encontrar una lista completa de cambios y mejoras en las notas de la versión .

Source: https://habr.com/ru/post/444862/


All Articles