Swift 5.0. Novidades

Swift 5 - o tão esperado lançamento, que inclui várias dezenas de melhorias e correções. Mas o principal objetivo do lançamento do Swift 5.0 era alcançar a estabilidade da ABI. Neste artigo, você aprenderá o que é ABI e qual ABI estável dará aos desenvolvedores do iOS / macOS. Também analisaremos vários novos recursos do Swift 5.



Estabilidade ABI


ABI é uma interface de aplicativo binária. Uma ABI pode ser vista como um conjunto de regras que permitem que um vinculador combine módulos componentes compilados.


Por conseguinte, o seguinte é descrito na ABI.


  1. O código de maneira é chamado a partir de diferentes módulos, incluindo os do sistema.
  2. O formato para passar argumentos e obter o valor de retorno das funções.
  3. Algoritmos de layout de dados de RAM.
  4. Gerenciamento de memória, ARC.
  5. Sistema de tipos, genéricos.

O Swift 5, juntamente com a ABI estável, fornece compatibilidade binária para aplicativos. A compatibilidade binária para aplicativos iOS / macOS significa que os aplicativos compilados serão compatíveis em tempo de execução com as bibliotecas do sistema compiladas por versões anteriores ou posteriores do idioma. Por exemplo, um aplicativo compilado com o Swift 5.0 será compatível com as bibliotecas padrão compiladas com o Swift 5.1 ou Swift 6.0.


A partir do iOS 12.2 e do macOS 10.14.4, os sistemas operacionais da Apple conterão tudo o que você precisa para executar aplicativos rápidos. Isso significa que os aplicativos escritos no Swift 5 e posterior não conterão tempo de execução e uma biblioteca de idiomas padrão. Portanto, os aplicativos escritos no Swift 5 pesam cerca de 3 a 10 megabytes a menos.


É importante observar que, além da estabilidade da ABI, também há estabilidade do módulo. Se a estabilidade da ABI permite combinar versões diferentes de um rápido em tempo de execução, a estabilidade do módulo é responsável por como as estruturas binárias escritas em diferentes versões da linguagem são compiladas. A estabilidade do módulo aparecerá no Swift 5.1. E então os desenvolvedores poderão distribuir suas estruturas não apenas de código aberto, mas também na forma compilada.


Profissionais da estabilidade da ABI.


  1. Os aplicativos pesam menos.
  2. Acelerando o desempenho de inicialização e aplicativos.
  3. Em teoria, a Apple poderia escrever novas estruturas inteiramente no Swift.

Contras ABI estabilidade.


Os desenvolvedores terão que considerar a falta de qualquer nova funcionalidade nas versões mais antigas da biblioteca padrão. Por exemplo, se o Swift 5.1 estiver incorporado no iOS 13 com algumas novas classes / funções na biblioteca padrão, com o suporte no iOS 12.2, os desenvolvedores não poderão usá-los. (Você precisará inserir verificações #available (...) da mesma maneira que fazemos agora para Foundation, UIKit e outras bibliotecas de plataforma).


Tipo de resultado na biblioteca padrão


Uma maneira padrão de transmitir e manipular erros na API assíncrona apareceu na biblioteca padrão. Você também pode usar esse tipo se, por algum motivo, o tratamento padrão de erros através de try / catch não for adequado.


O tipo de resultado é implementado através de enum com dois casos: sucesso e falha:


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

De fato, essa abordagem não é nova para os desenvolvedores do Swift. Desde a primeira versão do Swift, muitos desenvolvedores usam uma abordagem semelhante. Mas agora, quando o Resultado aparecer na biblioteca padrão, isso simplificará a interação com o código de bibliotecas externas.


Um exemplo de uso do serviço de download de artigos:


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

E aqui está um exemplo de processamento do resultado. Como Result é apenas uma enumeração, podemos processar todos os seus estados com uma opção:


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

Strings Raw


No Swift 5, eles adicionaram as chamadas seqüências brutas, nas quais aspas e barra invertida são interpretadas exatamente como caracteres, e você não precisa usar um caractere de escape para usá-los literalmente. Para escrever um literal para essa sequência, você deve adicionar o caractere # entre aspas duplas nas bordas.


Um exemplo de uso de aspas:


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

Esse recurso é especialmente útil ao escrever expressões regulares:


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

Para interpolar linhas após a barra invertida, adicione o caractere #:


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

Você pode ler mais nesta frase .


Interpolação de linha atualizada


Usando a interpolação de string, podemos adicionar o valor de uma variável ou o resultado de uma expressão a um literal de string. Começando com a 5ª versão do idioma, tornou-se possível expandir a maneira como nossas expressões são adicionadas à linha final.
Em geral, basta escrever uma extensão na estrutura DefaultStringInterpolation e adicionar um método chamado appendInterpolation. Por exemplo, se queremos adicionar um preço em um formato formatado a uma string:


 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 

É importante observar que, de fato, a construção (preço: 9,99) em uma cadeia de caracteres usando o compilador foi convertida em uma chamada para o método appendInterpolation (price: Decimal).
Também nos métodos appendInterpolation, podemos adicionar um número ilimitado de argumentos, nomeados e não nomeados, com ou sem valores padrão.


Você pode ler mais nesta frase .


Verificando a multiplicidade de números


O método de verificação da multiplicidade isMultiple (of :) foi adicionado aos tipos numéricos na biblioteca padrão. Sim, ainda podemos usar o operador para tirar o restante da divisão%. Mas parece que isMultiple (of :) parece mais visual.


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

Método CompactMapValues ​​no dicionário


O método compactMapValues ​​permite converter valores de dicionário e filtrá-los se a própria conversão retornar nulo.


Por exemplo, mapeando chaves de sequência para um 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] 

O segundo par de chave / valor foi excluído após o mapeamento, pois a sequência não é um URL válido.


Tente mudar o comportamento?


No Swift 4.2 usando a construção try? você pode facilmente obter um tipo opcional com vários níveis de aninhamento. Na maioria dos casos, não é isso que o desenvolvedor espera. Por esse motivo, no Swift 5, tente? obteve comportamento semelhante ao c encadeamento opcional. Ou seja, com uma combinação de tentativa? com encadeamento opcional ou conversão opcional, o resultado da expressão será opcional com um nível de aninhamento.


Tente o exemplo? junto com as?:


 // 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]? 

Tente o exemplo? junto com o 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 } 

Você pode ler mais nesta frase .


Atributo @DynamicCallable


O novo atributo @dynamicCallable permite marcar o tipo como "callable". Isso significa que podemos chamar o tipo como um método normal.
Se marcarmos o tipo como @dynamicCallable, devemos implementar um (ou ambos) dos métodos:


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

O tipo Arguments deve oferecer suporte ao protocolo ExpressibleByArrayLiteral, o tipo KeywordArguments deve suportar o protocolo ExpressibleByDictionaryLiteral e R1 e R2 podem ser de qualquer tipo.


Por exemplo, a estrutura de Sum. Ao ligar, você pode transferir qualquer número de números e obter a soma deles:


 @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 fato, o compilador converte sum (1, 2, 3, 4) em uma chamada para sum.dynamicallyCall (withArguments: [1, 2, 3, 4]). Da mesma forma, para o método dynamicallyCall (withKeywordArguments :).


Esse recurso permite adicionar a interação do código Swift com várias linguagens de programação dinâmica, por exemplo, Python ou JavaScript.


Você pode ler mais nesta frase .


Menos suporte do operador nas diretivas de versão do compilador e de verificação de idioma


Começando com a 5ª versão do Swift, você pode usar o operador "less" ao verificar a versão do compilador no código:


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

Conclusão


Esses não são todos os recursos e melhorias que apareceram no Swift 5. No total, foram aceitas 28 propostas da comunidade, que também incluíam a melhoria do desempenho da linha, o Swift Package Manager e a biblioteca padrão. Uma lista completa de alterações e melhorias pode ser encontrada nas notas de versão .

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


All Articles