Swift 5.0. Was gibt's Neues?

Swift 5 - die lang erwartete Veröffentlichung, die mehrere Dutzend Verbesserungen und Korrekturen enthält. Das Hauptziel der Veröffentlichung von Swift 5.0 war jedoch die Erreichung der ABI-Stabilität. In diesem Artikel erfahren Sie, was ABI ist und welche stabile ABI iOS / MacOS-Entwicklern bietet. Wir werden auch einige neue Funktionen von Swift 5 analysieren.



ABI-Stabilität


ABI ist eine binäre Anwendungsschnittstelle. Ein ABI kann als eine Reihe von Regeln betrachtet werden, die es einem Linker ermöglichen, kompilierte Komponentenmodule zu kombinieren.


Dementsprechend wird das Folgende in ABI beschrieben.


  1. Der Wegcode wird von verschiedenen Modulen aufgerufen, einschließlich Systemmodulen.
  2. Das Format zum Übergeben von Argumenten und zum Abrufen des Rückgabewerts von Funktionen.
  3. RAM-Datenlayout-Algorithmen.
  4. Speicherverwaltung, ARC.
  5. Typ System, Generika.

Swift 5 bietet zusammen mit stabilem ABI Binärkompatibilität für Anwendungen. Binäre Kompatibilität für iOS / macOS-Anwendungen bedeutet, dass kompilierte Anwendungen zur Laufzeit mit Systembibliotheken kompatibel sind, die von früheren oder späteren Versionen der Sprache kompiliert wurden. Beispielsweise ist eine mit Swift 5.0 kompilierte Anwendung mit Standardbibliotheken kompatibel, die mit Swift 5.1 oder Swift 6.0 kompiliert wurden.


Ab iOS 12.2 und macOS 10.14.4 enthalten die Betriebssysteme von Apple alles, was Sie zum Ausführen schneller Anwendungen benötigen. Dies bedeutet, dass in Swift 5 und höher geschriebene Anwendungen keine Laufzeit und keine Standard-Sprachbibliothek enthalten. Daher wiegen in Swift 5 geschriebene Anwendungen etwa 3-10 Megabyte weniger.


Es ist wichtig zu beachten, dass neben der ABI-Stabilität auch die Modulstabilität besteht. Wenn die ABI-Stabilität das Kombinieren verschiedener Versionen einer schnellen Laufzeit ermöglicht, ist die Modulstabilität dafür verantwortlich, wie in verschiedenen Versionen der Sprache geschriebene binäre Frameworks kompiliert werden. Die Modulstabilität wird in Swift 5.1 angezeigt. Und dann können Entwickler ihre Frameworks nicht nur Open Source, sondern auch in kompilierter Form verteilen.


Vorteile der ABI-Stabilität.


  1. Anwendungen wiegen weniger.
  2. Beschleunigung der Start- und Anwendungsleistung.
  3. Theoretisch könnte Apple neue Frameworks vollständig auf Swift schreiben.

Nachteile ABI-Stabilität.


Entwickler müssen das Fehlen neuer Funktionen in älteren Versionen der Standardbibliothek berücksichtigen. Wenn beispielsweise Swift 5.1 mit neuen Klassen / Funktionen in der Standardbibliothek in iOS 13 erstellt wurde, können Entwickler diese mit der Unterstützung in der iOS 12.2-Anwendung nicht verwenden. (Sie müssen #available (...) Checks genauso einfügen wie jetzt für Foundation, UIKit und andere Plattformbibliotheken.)


Ergebnistyp in der Standardbibliothek


In der Standardbibliothek wurde eine Standardmethode zum Übertragen und Behandeln von Fehlern in der asynchronen API angezeigt. Sie können diesen Typ auch verwenden, wenn aus irgendeinem Grund die Standardfehlerbehandlung durch try / catch nicht zu uns passt.


Der Ergebnistyp wird durch Aufzählung mit zwei Fällen implementiert: Erfolg und Misserfolg:


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

Tatsächlich ist dieser Ansatz für Swift-Entwickler nicht neu. Seit der ersten Version von Swift haben viele Entwickler einen ähnlichen Ansatz verwendet. Wenn das Ergebnis nun in der Standardbibliothek angezeigt wird, vereinfacht dies die Interaktion mit Code aus externen Bibliotheken.


Ein Beispiel für die Verwendung des Artikel-Download-Dienstes:


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

Und hier ist ein Beispiel für die Verarbeitung des Ergebnisses. Da das Ergebnis nur eine Aufzählung ist, können wir alle seine Zustände mit einem Schalter verarbeiten:


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

Rohe Saiten


In Swift 5 haben sie die sogenannten Raw-Strings hinzugefügt, in denen Anführungszeichen und Backslash genau als Zeichen interpretiert werden. Um sie in einem Literal zu verwenden, müssen Sie kein Escape-Zeichen verwenden. Um ein Literal für eine solche Zeichenfolge zu schreiben, müssen Sie das Zeichen # in doppelte Anführungszeichen an den Rändern einfügen.


Ein Beispiel für die Verwendung von Anführungszeichen:


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

Diese Funktion ist besonders nützlich, wenn Sie reguläre Ausdrücke schreiben:


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

Fügen Sie das Zeichen # hinzu, um Zeilen nach dem Backslash zu interpolieren:


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

Sie können mehr in diesem Satz lesen.


Aktualisierte Zeileninterpolation


Mithilfe der Zeichenfolgeninterpolation können wir den Wert einer Variablen oder das Ergebnis eines Ausdrucks zu einem Zeichenfolgenliteral hinzufügen. Ab der 5. Version der Sprache wurde es möglich, die Art und Weise zu erweitern, in der unsere Ausdrücke zur letzten Zeile hinzugefügt werden.
Schreiben Sie im Allgemeinen einfach eine Erweiterung in die DefaultStringInterpolation-Struktur und fügen Sie eine Methode namens appendInterpolation hinzu. Wenn wir beispielsweise einer Zeichenfolge einen Preis in formatierter Form hinzufügen möchten:


 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 ist wichtig zu beachten, dass die Konstruktion (Preis: 9,99) in der Zeichenfolge unter Verwendung des Compilers tatsächlich in einen Aufruf der Methode appendInterpolation (Preis: Dezimal) umgewandelt wurde.
Auch in den appendInterpolation-Methoden können wir eine unbegrenzte Anzahl von benannten und unbenannten Argumenten mit oder ohne Standardwerte hinzufügen.


Sie können mehr in diesem Satz lesen.


Überprüfen der Vielzahl von Zahlen


Die Methode zum Überprüfen der Multiplizität isMultiple (of :) wurde zu den numerischen Typen in der Standardbibliothek hinzugefügt. Ja, wir können den Operator weiterhin verwenden, um den Rest der Division% zu übernehmen. Aber es scheint, dass isMultiple (of :) visueller aussieht.


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

CompactMapValues-Methode im Wörterbuch


Mit der Methode compactMapValues ​​können Sie Wörterbuchwerte konvertieren und filtern, wenn die Konvertierung selbst null zurückgibt.


Beispiel: Zuordnen von Zeichenfolgenschlüsseln zu einem URL-Typ:


 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] 

Das zweite Schlüssel / Wert-Paar wurde nach der Zuordnung gelöscht, da die Zeichenfolge keine gültige URL ist.


Versuchen Sie, das Verhalten zu ändern?


In Swift 4.2 mit dem try-Konstrukt? Sie können problemlos einen optionalen Typ mit mehreren Verschachtelungsebenen erhalten. In den meisten Fällen ist dies nicht das, was der Entwickler erwartet. Aus diesem Grund in Swift 5 versuchen? Verhalten ähnlich wie bei optionaler Verkettung. Das heißt, mit einer Kombination von Versuch? Bei optionaler Verkettung oder optionalem Casting ist das Ergebnis des Ausdrucks optional mit einer Verschachtelungsebene.


Beispiel versuchen? zusammen mit als?:


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

Beispiel versuchen? zusammen mit der optionalen Objektmethode:


 // 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 } 

Sie können mehr in diesem Satz lesen.


@ DynamicCallable-Attribut


Mit dem neuen Attribut @dynamicCallable können Sie den Typ als "aufrufbar" markieren. Dies bedeutet, dass wir den Typ als normale Methode aufrufen können.
Wenn wir den Typ als @dynamicCallable markieren, müssen wir eine (oder beide) der folgenden Methoden implementieren:


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

Der Argumenttyp muss das ExpressibleByArrayLiteral-Protokoll unterstützen, der KeywordArguments-Typ muss das ExpressibleByDictionaryLiteral-Protokoll unterstützen und R1 und R2 können beliebige Typen sein.


Zum Beispiel die Struktur von Sum. Wenn Sie es anrufen, können Sie eine beliebige Anzahl von Nummern übertragen und deren Summe erhalten:


 @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 

Tatsächlich konvertiert der Compiler die Summe (1, 2, 3, 4) in einen Aufruf von sum.dynamicallyCall (withArguments: [1, 2, 3, 4]). Ähnliches gilt für die Methode dynamicCall (withKeywordArguments :).


Mit dieser Funktion können Sie die Interaktion von Swift-Code mit verschiedenen dynamischen Programmiersprachen wie Python oder JavaScript hinzufügen.


Sie können mehr in diesem Satz lesen.


Weniger Operatorunterstützung in Compiler-Versions- und Sprachprüfungsanweisungen


Ab der 5. Version von Swift können Sie den Operator "less" verwenden, wenn Sie die Compilerversion im Code überprüfen:


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

Fazit


Dies sind nicht alle Funktionen und Verbesserungen, die in Swift 5 veröffentlicht wurden. Insgesamt wurden 28 Vorschläge aus der Community angenommen, darunter auch die Verbesserung der Leitungsleistung, die Verbesserung des Swift Package Managers und der Standardbibliothek. Eine vollständige Liste der Änderungen und Verbesserungen finden Sie in den Versionshinweisen .

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


All Articles