Swift (Programmiersprache) - Swift (programming language)

Schnell
Swift-logo.svg
Logo
Paradigma Multiparadigma : protokollorientiert , objektorientiert , funktional , zwingend , blockstrukturiert , deklarativ
Entworfen von Chris Lattner , Doug Gregor, John McCall, Ted Kremenek, Joe Groff und Apple Inc.
Entwickler Apple Inc. und Open-Source-Mitwirkende
Erstmals erschienen 2. Juni 2014 ; vor 7 Jahren ( 2014-06-02 )
Stabile Version
5.4.2  Bearbeiten Sie dies auf Wikidata / 28. Juni 2021 ; vor 3 Monaten ( 28. Juni 2021 )
Vorschauversion
5.5 Filiale
Schreibdisziplin Statisch , stark , abgeleitet
Betriebssystem Apples Betriebssysteme ( Darwin , iOS , iPadOS , macOS , tvOS , watchOS ), Linux , Windows 10 , Android
Lizenz Apache License 2.0 (Swift 2.2 und höher)
Proprietär (bis Swift 2.2)
Dateinamenerweiterungen .schnell, .SWIFT
Webseite schnell .org
Beeinflusst von
Objective-C , Rust , Haskell , Ruby , Python , C# , CLU , D
Beeinflusst
Rost

Swift ist eine universelle , multiparadigmatische , kompilierte Programmiersprache, die von Apple Inc. und der Open-Source-Community entwickelt wurde . Swift wurde erstmals 2014 veröffentlicht und wurde als Ersatz für Apples frühere Programmiersprache Objective-C entwickelt , da Objective-C seit den frühen 1980er Jahren weitgehend unverändert geblieben war und moderne Sprachfunktionen fehlten. Swift arbeitet mit den Frameworks Cocoa und Cocoa Touch von Apple , und ein wichtiger Aspekt von Swifts Design war die Fähigkeit, mit dem riesigen Bestand an vorhandenem Objective-C-Code zu interagieren, der in den letzten Jahrzehnten für Apple-Produkte entwickelt wurde. Es wird mit dem Open-Source- LLVM- Compiler- Framework erstellt und ist seit Version 6, die 2014 veröffentlicht wurde, in Xcode enthalten . Auf Apple-Plattformen verwendet es die Objective-C- Laufzeitbibliothek , die C- , Objective-C- , C++- und Swift-Code ermöglicht innerhalb eines Programms ausführen.

Apple beabsichtigte, dass Swift viele Kernkonzepte im Zusammenhang mit Objective-C unterstützt , insbesondere dynamisches Dispatching , weit verbreitete späte Bindung , erweiterbare Programmierung und ähnliche Funktionen, jedoch auf "sicherere" Weise, um Softwarefehler leichter zu erkennen ; Swift verfügt über Funktionen, die einige häufige Programmierfehler wie die Nullzeiger- Dereferenzierung beheben, und bietet syntaktischen Zucker , um die Pyramide des Untergangs zu vermeiden . Swift unterstützt das Konzept der Protocol Extensibility, ein Erweiterbarkeitssystem, das auf Typen, Strukturen und Klassen angewendet werden kann , was Apple als echten Paradigmenwechsel in der Programmierung fördert, den sie "protokollorientierte Programmierung" (ähnlich wie Traits ) nennen.

Swift wurde auf der Worldwide Developers Conference (WWDC) von Apple 2014 vorgestellt. Es wurde 2014 ein Upgrade auf Version 1.2 und auf der WWDC 2015 ein großes Upgrade auf Swift 2 unterzogen. Ursprünglich eine proprietäre Sprache , wurde Version 2.2 am 3. Dezember 2015 unter der Apache-Lizenz 2.0 zu Open-Source-Software für Apples Plattformen und Linux gemacht .

Mit Version 3.0 wurde die Syntax von Swift erheblich weiterentwickelt, wobei das Kernteam die Quellstabilität zu einem Schwerpunkt in späteren Versionen machte. Im ersten Quartal 2018 übertraf Swift Objective-C an gemessener Popularität.

Swift 4.0, das 2017 veröffentlicht wurde, führte einige Änderungen an einigen integrierten Klassen und Strukturen ein. Code, der mit früheren Versionen von Swift geschrieben wurde, kann mithilfe der in Xcode integrierten Migrationsfunktionalität aktualisiert werden. Swift 5, das im März 2019 veröffentlicht wurde, führte eine stabile Binärschnittstelle auf Apple-Plattformen ein, die es ermöglichte, die Swift-Laufzeit in Apple-Betriebssysteme zu integrieren. Es ist quellkompatibel mit Swift 4.

Swift 5.1 wurde offiziell im September 2019 veröffentlicht. Swift 5.1 baut auf der vorherigen Version von Swift 5 auf, indem es die stabilen Funktionen der Sprache mit der Einführung der Modulstabilität zur Kompilierzeit erweitert. Die Einführung der Modulstabilität ermöglicht es, binäre Frameworks zu erstellen und zu teilen, die mit zukünftigen Versionen von Swift funktionieren.

Swift 5.5, offiziell von Apple auf der WWDC 2021 angekündigt , erweitert die Sprachunterstützung für Parallelität und asynchronen Code erheblich und führt insbesondere eine einzigartige Version des Akteurmodells ein .

Geschichte

Die Entwicklung von Swift begann im Juli 2010 von Chris Lattner in Zusammenarbeit mit vielen anderen Programmierern bei Apple . Swift nahm Sprachideen "von Objective-C , Rust , Haskell , Ruby , Python , C# , CLU und viel zu vielen anderen, um sie aufzulisten". Am 2. Juni 2014 wurde die App Apple Worldwide Developers Conference (WWDC) die erste öffentlich veröffentlichte App, die mit Swift geschrieben wurde. Eine Beta-Version der Programmiersprache wurde auf der Konferenz für registrierte Apple-Entwickler freigegeben, aber das Unternehmen versprach nicht, dass die endgültige Version von Swift Quellcode- kompatibel mit der Testversion sein würde. Apple plante, bei Bedarf für die vollständige Version Quellcodekonverter zur Verfügung zu stellen.

Die Swift Programming Language , ein kostenloses 500-seitiges Handbuch, wurde ebenfalls auf der WWDC veröffentlicht und ist im Apple Books Store und auf der offiziellen Website erhältlich.

Swift erreichte am 9. September 2014 mit dem Gold Master von Xcode 6.0 für iOS den Meilenstein 1.0 . Swift 1.1 wurde am 22. Oktober 2014 zusammen mit der Einführung von Xcode 6.1 veröffentlicht. Swift 1.2 wurde am 8. April 2015 zusammen mit Xcode 6.3 veröffentlicht. Swift 2.0 wurde auf der WWDC 2015 angekündigt und am 21. September 2015 für die Veröffentlichung von Apps im App Store zur Verfügung gestellt. Swift 3.0 wurde am 13. September 2016 veröffentlicht. Swift 4.0 wurde am 19. September 2017 veröffentlicht. Swift 4.1 wurde am veröffentlicht 29. März 2018.

Swift gewann den ersten Platz für die beliebteste Programmiersprache in der Stack Overflow Developer Survey 2015 und den zweiten Platz 2016.

Am 3. Dezember 2015 wurden die Swift-Sprache, unterstützende Bibliotheken, Debugger und Paketmanager unter der Apache 2.0-Lizenz mit einer Laufzeitbibliotheksausnahme als Open Source bereitgestellt , und Swift.org wurde erstellt, um das Projekt zu hosten. Der Quellcode wird auf GitHub gehostet , wo jeder leicht den Code abrufen, selbst erstellen und sogar Pull-Requests erstellen kann, um Code zurück zum Projekt beizutragen.

Im Dezember 2015 kündigte IBM seine Swift Sandbox-Website an, die es Entwicklern ermöglicht, Swift-Code in einem Bereich zu schreiben und die Ausgabe in einem anderen anzuzeigen. Die Swift Sandbox wurde im Januar 2018 eingestellt.

Während der WWDC 2016 kündigte Apple eine exklusive iPad- App namens Swift Playgrounds an , die den Leuten beibringen soll, wie man in Swift programmiert. Die App wird in einer 3D-Videospiel-ähnlichen Oberfläche präsentiert, die Feedback gibt, wenn Codezeilen in einer bestimmten Reihenfolge platziert und ausgeführt werden.

Im Januar 2017 gab Chris Lattner seinen Abschied von Apple für eine neue Position bei Tesla Motors bekannt , wobei die Hauptrolle des Swift-Projekts an Teamveteran Ted Kremenek geht.

Während der WWDC 2019 kündigte Apple SwiftUI mit Xcode 11 an, das ein Framework für das deklarative UI-Strukturdesign auf allen Apple-Plattformen bietet.

Offizielle Downloads für die Ubuntu- Distribution von Linux sind seit Swift 2.2 verfügbar, weitere Distributionen wurden seit Swift 5.2.4, CentOS und Amazon Linux hinzugefügt . Es gibt auch ein inoffizielles SDK und ein natives Toolchain-Paket für Android.

Plattformen

Die von Swift unterstützten Plattformen sind Apples Betriebssysteme ( Darwin , iOS , iPadOS , macOS , tvOS , watchOS ), Linux , Windows und Android .

Versionsgeschichte

Ausführung Veröffentlichungsdatum Mac OS Linux Fenster
Schnell 1.0 9. September 2014 Jawohl Nein Nein
Schnell 1,1 22. Oktober 2014 Jawohl Nein Nein
Schnell 1,2 8. April 2015 Jawohl Nein Nein
Schnell 2.0 21. September 2015 Jawohl Nein Nein
Schnell 2,1 20. Oktober 2015 Jawohl Nein Nein
Schnell 2.2 21. März 2016 Jawohl Jawohl Nein
Schnell 2.2.1 3. Mai 2016 Jawohl Jawohl Nein
Schnell 3.0 13. September 2016 Jawohl Jawohl Nein
Schnell 3.0.1 28. Oktober 2016 Jawohl Jawohl Nein
Schnell 3.0.2 13. Dezember 2016 Jawohl Jawohl Nein
Schnell 3.1 27. März 2017 Jawohl Jawohl Nein
Schnell 3.1.1 21. April 2017 Jawohl Jawohl Nein
Schnell 4.0 19. September 2017 Jawohl Jawohl Nein
Schnell 4.0.2 1. November 2017 Jawohl Jawohl Nein
Schnell 4.0.3 5. Dezember 2017 Jawohl Jawohl Nein
Schnell 4.1 29. März 2018 Jawohl Jawohl Nein
Schnell 4.1.1 4. Mai 2018 Nein Jawohl Nein
Schnell 4.1.2 31. Mai 2018 Jawohl Jawohl Nein
Schnell 4.1.3 27. Juli 2018 Nein Jawohl Nein
Schnell 4,2 17. September 2018 Jawohl Jawohl Nein
Schnell 4.2.1 30. Oktober 2018 Jawohl Jawohl Nein
Schnell 4.2.2 4. Februar 2019 Nein Jawohl Nein
Schnell 4.2.3 28. Februar 2019 Nein Jawohl Nein
Schnell 4.2.4 29. März 2019 Nein Jawohl Nein
Schnell 5.0 25. März 2019 Jawohl Jawohl Nein
Schnell 5.0.1 18. April 2019 Jawohl Jawohl Nein
Schnell 5.0.2 15. Juli 2019 Nein Jawohl Nein
Schnell 5.0.3 30. August 2019 Nein Jawohl Nein
Schnelle 5.1 10. September 2019 Jawohl Jawohl Nein
Schnell 5.1.1 11. Oktober 2019 Nein Jawohl Nein
Schnell 5.1.2 7. November 2019 Jawohl Jawohl Nein
Schnell 5.1.3 13. Dezember 2019 Jawohl Jawohl Nein
Schnell 5.1.4 31. Januar 2020 Nein Jawohl Nein
Schnell 5.1.5 9. März 2020 Nein Jawohl Nein
Schnell 5.2 24. März 2020 Jawohl Jawohl Nein
Schnell 5.2.1 30. März 2020 Nein Jawohl Nein
Schnell 5.2.2 15. April 2020 Jawohl Jawohl Nein
Schnell 5.2.3 29. April 2020 Nein Jawohl Nein
Schnell 5.2.4 20. Mai 2020 Jawohl Jawohl Nein
Schnell 5.2.5 5. August 2020 Nein Jawohl Nein
Schnell 5,3 16. September 2020 Jawohl Jawohl Jawohl
Schnell 5.3.1 13. November 2020 Jawohl Jawohl Jawohl
Schnell 5.3.2 15. Dezember 2020 Jawohl Jawohl Jawohl
Schnell 5.3.3 25. Januar 2021 Nein Jawohl Jawohl
Schnell 5,4 26. April 2021 Jawohl Jawohl Jawohl
Schnell 5.4.1 25. Mai 2021 Nein Jawohl Jawohl
Schnell 5.4.2 28. Juni 2021 Jawohl Jawohl Jawohl
Schnell 5.4.3 9. September 2021 Nein Jawohl Jawohl
Schnell 5.5 20. September 2021 Jawohl Jawohl Jawohl

Merkmale

Swift ist eine Alternative zur Objective-C- Sprache, die moderne Konzepte der Programmiersprachentheorie verwendet und eine einfachere Syntax anstrebt. Bei seiner Einführung wurde es einfach als "Ziel-C ohne das Gepäck von C" beschrieben.

Standardmäßig macht Swift keine Zeiger und andere unsichere Zugriffsmethoden verfügbar , im Gegensatz zu Objective-C, das Zeiger durchdringend verwendet, um auf Objektinstanzen zu verweisen. Außerdem wurde die Verwendung einer Smalltalk- ähnlichen Syntax in Objective-C zum Ausführen von Methodenaufrufen durch einen Punktnotationsstil und ein Namespace- System ersetzt, das Programmierern aus anderen gängigen objektorientierten (OO) Sprachen wie Java oder C# vertraut ist . Swift führt echte benannte Parameter ein und behält wichtige Objective-C-Konzepte bei, einschließlich Protokolle , Closures und Kategorien , wobei die frühere Syntax oft durch sauberere Versionen ersetzt wird und diese Konzepte auf andere Sprachstrukturen wie Aufzählungstypen (Enumerationen) angewendet werden können.

Verschlussunterstützung

Swift unterstützt Verschlüsse ( in anderen Sprachen als Lambdas bekannt ). Closures sind in sich geschlossene Funktionsblöcke, die weitergegeben und in Ihrem Code verwendet werden können. Closures kann man sich als unbenannte Funktion vorstellen. Hier ist ein Beispiel:

// Closure type, defined by its input and output values, can be specified outside the closure:
let closure1: (Int, Int) -> Int = { arg1, arg2 in
    return arg1 + arg2
}

// …or inside it:
let closure2 = { (arg1: Int, arg2: Int) -> Int in
    return arg1 + arg2
}

// In most cases, closure’s return type can be inferred automatically by the compiler.
// However, this functionality may not work for too complex expressions.
let closure3 = { arg1: Int, arg2: Int in
    return arg1 + arg2
}

Swift hat eine nachgestellte Closure-Syntax wie diese:

// This function takes a closure which receives no input parameters and returns an integer,
// evaluates it, and uses the closure’s return value (an Int) as the function’s return value.
func foo(closure bar: () -> Int) -> Int {
    return bar()
}

// Without trailing closure syntax:
foo(closure: { return 1 })

// With trailing closure syntax:
foo { return 1 }

Ab Version 5.3 unterstützt Swift mehrere Trailing Closures:

// This function passes the return of the first closure as the parameter of the second,
// and returns the second closure’s result:
func foo(bar: () -> Int, baz: (Int) -> Int) -> Int {
    return baz(bar())
}

// With no trailing closures:
foo(bar: { return 1 }, baz: { x in return x + 1 })

// With 1 trailing closure:
a(bar: { return 1 }) { x in return x + 1 })

// With 2 trailing closures (note that only the first closure’s argument name is ommited):
a { return 1 } baz: { x in return x + 1 }

Hier sind die Kriterien für die nachgestellte Closure-Syntax:

  • Wenn die letzten Argumente einer Funktion Closures sind, können Sie die abschließende Closure-Syntax verwenden.
  • Der Parametername des ersten abschließenden Closures muss weggelassen werden.
  • Die Parameternamen der verbleibenden abschließenden Closures dürfen nicht ausgelassen werden.
  • Wenn alle einer Funktion übergebenen Argumente abschließende Closures sind, können Sie die Klammern nach dem Namen der Funktion weglassen.
  • Aufrufe einer Funktion mit abschließenden Closures müssen in Klammern gesetzt werden, wenn sie in einer guardAnweisung verwendet werden.

String-Unterstützung

In den Umgebungen Cocoa und Cocoa Touch waren viele gängige Klassen Teil der Foundation Kit- Bibliothek. Dazu gehörten die NSString-Zeichenfolgenbibliothek (mit Unicode , UTF-8 in Swift 5, geändert von UTF-16 ), die Sammlungsklassen NSArray und NSDictionary und andere. Objective-C lieferte verschiedene syntaktische Zuckerstücke , damit einige dieser Objekte spontan innerhalb der Sprache erstellt werden konnten, aber sobald sie erstellt waren, wurden die Objekte mit Objektaufrufen manipuliert. In Objective-C sind zum Beispiel beim Verketten von zwei NSStrings erforderliche Methodenaufrufe ähnlich wie folgt:

NSString *str = @"hello,";
str = [str stringByAppendingString:@" world"];

In Swift wurden viele dieser Grundtypen zum Kern der Sprache befördert und können direkt manipuliert werden. Strings werden beispielsweise unsichtbar mit NSString verbunden (wenn Foundation importiert wird) und können jetzt mit dem +Operator verkettet werden, was eine stark vereinfachte Syntax ermöglicht; das vorherige Beispiel wird:

var str = "hello,"
str += " world"

Zugangskontrolle

Swift unterstützt fünf Zugriffskontrollstufen für Symbole: open, public, internal, fileprivate, und private. Im Gegensatz zu vielen objektorientierten Sprachen ignorieren diese Zugriffskontrollen Vererbungshierarchien : privatezeigt an, dass ein Symbol nur im unmittelbaren Geltungsbereichfileprivate zugänglich ist , zeigt an , dass es nur innerhalb der Datei internalzugänglich ist , gibt an , dass es innerhalb des enthaltenden Moduls publiczugänglich ist , gibt an , dass es von zugänglich ist ein beliebiges Modul und open(nur für Klassen und ihre Methoden) gibt an, dass die Klasse außerhalb des Moduls untergeordnet werden kann.

Optionen und Verkettung

Ein wichtiges neues Feature in Swift sind Optionstypen , die es ermöglichen, dass Referenzen oder Werte auf ähnliche Weise wie das allgemeine Muster in C funktionieren , bei dem ein Zeiger auf einen Wert verweisen oder null sein kann. Dies impliziert, dass nicht-optionale Typen nicht zu einem Null-Zeiger-Fehler führen können ; der Compiler kann sicherstellen, dass dies nicht möglich ist.

Optionale Typen werden mit dem OptionalMechanismus erstellt – um eine Integer zu machen, die nullfähig ist, würde man eine Deklaration ähnlich wie verwenden var optionalInteger: Optional<Int>. Wie in C# enthält Swift dafür auch syntaktischen Zucker, der es einem ermöglicht, anzugeben, dass eine Variable optional ist, indem man ein Fragezeichen hinter den Typnamen setzt, var optionalInteger: Int?. Als optional gekennzeichnete Variablen oder Konstanten haben entweder einen Wert des zugrunde liegenden Typs oder sind nil. Optionale Typen umschließen den Basistyp, was zu einer anderen Instanz führt. Stringund String?sind grundverschiedene Typen, wobei letztere mehr mit Int?als gemeinsam haben String.

Um auf den darin enthaltenen Wert zuzugreifen, muss er, sofern er nicht nil ist, entpackt werden , um die darin enthaltene Instanz verfügbar zu machen. Dies geschieht mit dem !Operator:

let myValue = anOptionalInstance!.someMethod()

In diesem Fall !entpackt der Operator anOptionalInstance, um die darin enthaltene Instanz verfügbar zu machen, sodass der Methodenaufruf darauf erfolgen kann. Wenn anOptionalInstancenil ist, tritt ein Null-Zeiger-Fehler auf. Dies kann in der Praxis ärgerlich sein, daher beinhaltet Swift auch das Konzept der optionalen Verkettung , um zu testen, ob die Instanz nil ist, und sie dann zu entpacken, wenn sie nicht null ist:

let myValue = anOptionalInstance?.someMethod()

In diesem Fall ruft die Laufzeit someMethodnur auf, wenn anOptionalInstancenicht nil ist, wodurch der Fehler unterdrückt wird. Normalerweise erfordert dies, dass der Programmierer testet, ob myValuenil ist, bevor er fortfährt. Der Begriff Verkettung stammt aus dem häufigeren Fall, bei dem mehrere Methodenaufrufe/Getter miteinander verkettet werden. Zum Beispiel:

let aTenant = aBuilding.tenantList[5]
let theirLease = aTenant.leaseDetails
let leaseStart = theirLease?.startDate

kann reduziert werden auf:

let leaseStart = aBuilding.tenantList[5].leaseDetails?.startDate

Die ?Syntax umgeht die Pyramide des Untergangs .

In Swift 2 wurde das neue Schlüsselwort guardfür Fälle eingeführt, in denen die Ausführung von Code gestoppt werden sollte, wenn eine Bedingung nicht erfüllt ist:

guard let leaseStart = aBuilding.TenantList[5]?.leaseDetails?.startDate else
{
    //handle the error case where anything in the chain is nil
    //else scope must exit the current method or loop
}
//continue, knowing that leaseStart is not nil

Die Verwendung guardhat drei Vorteile. Die Syntax kann zwar als ifAnweisung fungieren , ihr Hauptvorteil besteht jedoch darin, dass sie keine NULL-Zulässigkeit besitzt. Wenn eine ifAnweisung einen Fall erfordert, wird guardder Fall basierend auf der bereitgestellten Bedingung angenommen. Da guardmit Ausnahme des elseVerschlusses leaseStartkein Zielfernrohr enthalten ist , wird es als unverpacktes optionales Zubehör zum Super-Zielfernrohr der Wache präsentiert. Wenn der guardTest der Anweisung fehlschlägt, erfordert Swift schließlich, dass elsedie aktuelle Methode oder Schleife beendet wird, um sicherzustellen, dass leaseStartnie auf zugegriffen wird, wenn nil. Dies geschieht mit den Schlüsselwörtern return, continue, break, oder throw, oder durch Aufrufen einer Funktion, die ein zurückgibt Never(zB fatalError()).

Objective-C war schwach typisiert und erlaubte jederzeit den Aufruf jeder Methode für jedes Objekt. Wenn der Methodenaufruf fehlgeschlagen ist, gab es in der Laufzeit einen Standardhandler, der nil zurückgab. Das bedeutete, dass kein Auspacken oder Testen erforderlich war, die entsprechende Aussage in Objective-C:

leaseStart = [[[aBuilding tenantList:5] leaseDetails] startDate]

Würde Null zurückgeben, und dies könnte getestet werden. Dies erforderte jedoch auch, dass alle Methodenaufrufe dynamisch sind, was einen erheblichen Overhead mit sich bringt. Die Verwendung von Optionals durch Swift bietet einen ähnlichen Mechanismus zum Testen und Behandeln von Nullen, jedoch auf eine Weise, die es dem Compiler ermöglicht, statischen Dispatch zu verwenden, da die Entpackaktion für eine definierte Instanz (den Wrapper) aufgerufen wird, anstatt im Laufzeit-Dispatch System.

Werttypen

In vielen objektorientierten Sprachen werden Objekte intern in zwei Teilen dargestellt. Das Objekt wird als ein auf dem Heap platzierter Datenblock gespeichert , während der Name (oder "Handle") zu diesem Objekt durch einen Zeiger repräsentiert wird . Objekte werden zwischen Methoden übergeben, indem der Wert des Zeigers kopiert wird, sodass jeder mit einer Kopie auf dieselben zugrunde liegenden Daten auf dem Heap zugreifen kann. Im Gegensatz dazu werden grundlegende Typen wie Integer und Gleitkommawerte direkt dargestellt; das Handle enthält die Daten, keinen Zeiger darauf, und diese Daten werden durch Kopieren direkt an Methoden übergeben. Diese Zugriffsarten werden im Fall von Objekten als Referenzübergabe und für Basistypen als Wertübergabe bezeichnet .

Beide Konzepte haben ihre Vor- und Nachteile. Objekte sind nützlich, wenn die Daten groß sind, wie die Beschreibung eines Fensters oder der Inhalt eines Dokuments. In diesen Fällen erfolgt der Zugriff auf diese Daten durch das Kopieren eines 32- oder 64-Bit-Werts im Gegensatz zum Kopieren einer gesamten Datenstruktur. Kleinere Werte wie ganze Zahlen haben jedoch die gleiche Größe wie Zeiger (normalerweise sind beide ein Wort ), sodass die Übergabe eines Zeigers gegenüber der Übergabe des Werts keinen Vorteil hat. Außerdem erfordert die Referenzübergabe von Natur aus eine Dereferenzierungsoperation, die bei einigen Operationen, typischerweise solchen, die mit diesen grundlegenden Werttypen wie Mathematik verwendet werden, einen erheblichen Overhead verursachen kann.

Ähnlich wie C# und im Gegensatz zu den meisten anderen OO-Sprachen bietet Swift integrierte Unterstützung für Objekte, die entweder eine Referenzübergabe- oder eine Wertübergabesemantik verwenden, wobei erstere die classDeklaration verwendet und letztere struct. Structs in Swift haben fast alle die gleichen Funktionen wie Klassen: Methoden, Implementierung von Protokollen und Verwendung der Erweiterungsmechanismen. Aus diesem Grund bezeichnet Apple alle Daten generisch als Instanzen im Gegensatz zu Objekten oder Werten. Strukturen unterstützen jedoch keine Vererbung.

Der Programmierer kann frei wählen, welche Semantik für jede Datenstruktur in der Anwendung besser geeignet ist. Größere Strukturen wie Fenster würden als Klassen definiert, so dass sie als Zeiger weitergegeben werden können. Kleinere Strukturen, wie ein 2D-Punkt, können als Strukturen definiert werden, die als Wert übergeben werden und einen direkten Zugriff auf ihre internen Daten ohne Dereferenzierung ermöglichen. Die dem Konzept der Wertübergabe innewohnende Leistungsverbesserung besteht darin, dass Swift diese Typen für fast alle gängigen Datentypen verwendet, einschließlich Intund Double, und Typen, die normalerweise durch Objekte wie Stringund dargestellt werden Array. Die Verwendung von Werttypen kann auch in Benutzeranwendungen zu erheblichen Leistungsverbesserungen führen.

Um sicherzustellen, dass selbst die größten Strukturen bei der Übergabe keine Leistungseinbußen verursachen, verwendet Swift das Kopieren beim Schreiben, sodass die Objekte nur dann kopiert werden, wenn das Programm versucht, einen Wert in ihnen zu ändern. Dies bedeutet, dass die verschiedenen Zugriffsmethoden praktisch einen Zeiger auf denselben Datenspeicher haben. Während die Daten also physisch als eine Instanz im Speicher gespeichert werden, sind diese Werte auf Anwendungsebene getrennt und die physische Trennung wird nur bei Bedarf durch Kopieren beim Schreiben erzwungen.

Protokollorientierte Programmierung

Ein Schlüsselmerkmal von Objective-C ist die Unterstützung von Kategorien , Methoden, die hinzugefügt werden können, um Klassen zur Laufzeit zu erweitern. Kategorien ermöglichen das Erweitern von Klassen an Ort und Stelle, um neue Funktionen hinzuzufügen, ohne dass Unterklassen erstellt werden müssen oder sogar Zugriff auf den ursprünglichen Quellcode besteht . Ein Beispiel könnte sein, der Basisklasse die Unterstützung der Rechtschreibprüfung hinzuzufügen NSString, was bedeutet, dass alle Instanzen von NSString in der Anwendung eine Rechtschreibprüfung erhalten. Das System wird auch häufig als Organisationstechnik verwendet, die es ermöglicht, verwandten Code in bibliotheksähnlichen Erweiterungen zu sammeln. Swift unterstützt dieses Konzept weiterhin, obwohl sie jetzt als Erweiterungen bezeichnet und mit dem Schlüsselwort deklariert werden extension. Im Gegensatz zu Objective-C kann Swift auch vorhandenen Instanzen neue Eigenschaftenzugriffsmethoden, Typen und Aufzählungen hinzufügen.

Ein weiteres wichtiges Merkmal von Objective-C ist die Verwendung von Protokollen , die in den meisten modernen Sprachen als Schnittstellen bekannt sind . Protokolle versprechen, dass eine bestimmte Klasse eine Reihe von Methoden implementiert, was bedeutet, dass andere Objekte im System diese Methoden für jedes Objekt aufrufen können, das dieses Protokoll unterstützt. Dies wird in modernen OO-Sprachen oft als Ersatz für die Mehrfachvererbung verwendet , obwohl die Feature-Sets nicht ganz ähnlich sind. Ein gängiges Beispiel für ein Protokoll in Cocoa ist das NSCopyingProtokoll, das eine Methode definiert copyWithZone, die Deep-Copying auf Objekten implementiert .

In Objective-C und den meisten anderen Sprachen, die das Protokollkonzept implementieren, liegt es am Programmierer, sicherzustellen, dass die erforderlichen Methoden in jeder Klasse implementiert werden. Swift bietet die Möglichkeit, diese Methoden mithilfe von Erweiterungen hinzuzufügen und generische Programmierung (Generik) zu verwenden, um sie zu implementieren. In Kombination ermöglichen diese das einmalige Schreiben von Protokollen und unterstützen eine Vielzahl von Instanzen. Außerdem kann der Erweiterungsmechanismus verwendet werden, um einem Objekt, das dieses Protokoll nicht in seiner Definition aufführt, Protokollkonformität hinzuzufügen.

Beispielsweise könnte ein Protokoll als als aufgerufen deklariert werden StringConvertible, wodurch sichergestellt wird, dass protokollkonforme Instanzen eine toStringMethode implementieren, die eine zurückgibt String. In Swift kann dies mit folgendem Code deklariert werden:

protocol StringConvertible
{
    func toString() -> String
}

Dieses Protokoll kann jetzt zu String hinzugefügt werden, ohne Zugriff auf die Quelle der Basisklasse:

extension String: StringConvertible
{
    func toString() -> String
    {
        self
    }
}

In Swift können, wie in vielen modernen Sprachen, die Schnittstellen unterstützen, Protokolle als Typen verwendet werden, was bedeutet, dass Variablen und Methoden durch das Protokoll anstelle ihres spezifischen Typs definiert werden können:

var someSortOfPrintableObject: StringConvertible
...
print(someSortOfPrintableObject.toString())

Es spielt keine Rolle, um welche Art von Instanz es sich someSortOfPrintableObjecthandelt, der Compiler stellt sicher, dass es dem Protokoll entspricht und somit dieser Code sicher ist. Diese Syntax bedeutet auch, dass Sammlungen auch auf Protokollen basieren können, wie let printableArray = [StringConvertible].

Da Swift Strukturen und Klassen als ähnliche Konzepte behandelt, werden sowohl Erweiterungen als auch Protokolle in der Laufzeit von Swift ausgiebig verwendet, um eine umfangreiche API basierend auf Strukturen bereitzustellen. Zum Beispiel verwendet Swift eine Erweiterung, um das EquatableProtokoll zu vielen ihrer Grundtypen wie Strings und Arrays hinzuzufügen , sodass sie mit dem ==Operator verglichen werden können. Ein konkretes Beispiel für das Zusammenspiel all dieser Funktionen kann im Konzept der Standardprotokollimplementierungen gesehen werden :

func !=<T : Equatable>(lhs: T, rhs: T) -> Bool

Diese Funktion definiert eine Methode, die auf jeder Instanz, die konform Equatableist, funktioniert und eine ungleiche Funktion bereitstellt . Jede Instanz, Klasse oder Struktur erhält diese Implementierung automatisch, indem sie sich einfach an Equatable. Da viele Instanzen Equatabledurch ihre Basisimplementierungen oder andere generische Erweiterungen gewinnen, gewinnen die meisten grundlegenden Objekte in der Laufzeit ohne Code gleich und nicht gleich.

Diese Kombination von Protokollen, Standardwerten, Protokollvererbung und Erweiterungen ermöglicht die Implementierung vieler Funktionen, die normalerweise mit Klassen und Vererbung verbunden sind, auf Werttypen. Bei richtiger Anwendung kann dies zu dramatischen Leistungsverbesserungen ohne nennenswerte API-Einschränkungen führen. Dieses Konzept ist innerhalb von Swift so weit verbreitet, dass Apple es als protokollorientierte Programmiersprache bezeichnet . Sie schlagen vor, viele der Problemdomänen anzugehen, die normalerweise durch Klassen und Vererbung gelöst werden, indem stattdessen Protokolle und Strukturen verwendet werden.

Bibliotheken, Laufzeit und Entwicklung

Auf Apple-Systemen verwendet Swift dieselbe Laufzeit wie das vorhandene Objective-C- System, erfordert jedoch iOS 7 oder macOS 10.9 oder höher. Es hängt auch von Grand Central Dispatch ab . Swift- und Objective-C-Code können in einem Programm verwendet werden, und als Erweiterung auch C und C++. Im Gegensatz zu C kann C++- Code nicht direkt aus Swift heraus verwendet werden. Zwischen Swift und C++ muss ein Objective-C- oder C-Wrapper erstellt werden. Im Fall von Objective-C hat Swift erheblichen Zugriff auf das Objektmodell und kann verwendet werden, um Objective-C-Code unterzuordnen, zu erweitern und zu verwenden, um Protokollunterstützung bereitzustellen. Das Gegenteil ist nicht der Fall: Eine Swift-Klasse kann in Objective-C nicht untergeordnet werden.

Um die Entwicklung solcher Programme und die Wiederverwendung von vorhandenem Code zu unterstützen, bietet Xcode 6 und höher ein halbautomatisches System, das einen Bridging-Header erstellt und verwaltet , um Objective-C-Code für Swift bereitzustellen. Dies geschieht in Form einer zusätzlichen Header-Datei , die einfach alle Objective-C-Symbole definiert oder importiert, die vom Swift-Code des Projekts benötigt werden. An diesem Punkt kann Swift auf die Typen, Funktionen und Variablen verweisen, die in diesen Importen deklariert wurden, als wären sie in Swift geschrieben. Objective-C-Code kann auch Swift-Code direkt verwenden, indem eine automatisch verwaltete Header-Datei mit Objective-C-Deklarationen der Swift-Symbole des Projekts importiert wird. Beispielsweise könnte eine Objective-C-Datei in einem gemischten Projekt namens "MyApp" mit dem Code auf Swift-Klassen oder -Funktionen zugreifen #import "MyApp-Swift.h". Durch diesen Mechanismus sind jedoch nicht alle Symbole verfügbar – die Verwendung von Swift-spezifischen Funktionen wie generischen Typen, optionalen Typen ohne Objekt, komplexen Aufzählungen oder sogar Unicode-Bezeichnern kann dazu führen, dass ein Symbol von Objective-C aus nicht mehr zugänglich ist.

Swift bietet auch eingeschränkte Unterstützung für Attribute , Metadaten, die von der Entwicklungsumgebung gelesen werden und nicht unbedingt Teil des kompilierten Codes sind. Wie bei Objective-C verwenden Attribute die @Syntax, aber die derzeit verfügbare Menge ist klein. Ein Beispiel ist das @IBOutletAttribut, das einen bestimmten Wert im Code als Ausgang markiert , der für die Verwendung im Interface Builder (IB) verfügbar ist . Ein Outlet ist ein Gerät, das den Wert der Bildschirmanzeige an ein Objekt im Code bindet.

Auf Nicht-Apple-Systemen ist Swift nicht von einer Objective-C-Laufzeit oder anderen Apple-Systembibliotheken abhängig; eine Reihe von Swift "Corelib"-Implementierungen ersetzen sie. Dazu gehören eine "swift-corelibs-foundation" für das Foundation Kit , eine "swift-corelibs-libdispatch" für den Grand Central Dispatch und eine "swift-corelibs-xctest" für den XCTest APIs von Xcode .

Ab 2019 hat Apple mit Xcode 11 auch ein wichtiges neues UI-Paradigma namens SwiftUI hinzugefügt. SwiftUI ersetzt das ältere Interface Builder- Paradigma durch ein neues deklaratives Entwicklungsparadigma.

Speicherverwaltung

Swift verwendet Automatic Reference Counting (ARC), um den Speicher zu verwalten . Apple verlangte in Objective-C eine manuelle Speicherverwaltung, führte jedoch 2011 ARC ein, um eine einfachere Speicherzuweisung und -freigabe zu ermöglichen. Ein Problem mit ARC ist die Möglichkeit, einen starken Referenzzyklus zu erstellen , in dem Objekte so aufeinander verweisen, dass Sie das Objekt, von dem Sie ausgegangen sind, erreichen können, indem Sie Referenzen folgen (zB A-Referenzen B, B-Referenzen A). Dies führt dazu, dass sie in den Speicher gelangen, da sie nie freigegeben werden. Swift liefert die Schlüsselwörter weakund unownedverhindert starke Referenzzyklen. In der Regel verwendet eine Eltern-Kind-Beziehung eine starke Referenz, während ein Kind-Elternteil eine weakReferenz verwenden würde, bei der Eltern und Kinder nicht miteinander verwandt sein können oder bei unowneddenen ein Kind immer ein Elternteil hat, aber ein Elternteil möglicherweise kein Kind hat. Schwache Referenzen müssen optionale Variablen sein, da sie sich ändern und zu nil.

Ein Abschluss innerhalb einer Klasse kann auch einen starken Referenzzyklus erzeugen, indem Selbstreferenzen erfasst werden. Selbstreferenzen, die als schwach oder nicht im Besitz zu behandeln sind, können mithilfe einer Erfassungsliste angegeben werden .

Debugging und andere Elemente

Ein Schlüsselelement des Swift-Systems ist seine Fähigkeit, mit Hilfe einer Read-Eval-Print-Schleife (REPL) sauber gedebuggt und innerhalb der Entwicklungsumgebung ausgeführt zu werden , was ihm interaktive Eigenschaften verleiht, die eher mit den Skriptfähigkeiten von Python als mit der traditionellen Systemprogrammierung übereinstimmen Sprachen. Die REPL wird durch Playgrounds , interaktive Ansichten, die innerhalb der Xcode-Umgebung laufen und auf Code- oder Debugger-Änderungen spontan reagieren, weiter verbessert . Playgrounds ermöglichen es Programmierern, Swift-Code zusammen mit der Markdown-Dokumentation hinzuzufügen. Wenn sich Code im Laufe der Zeit oder in Bezug auf einen anderen Bereichseingabewert ändert, kann die Ansicht mit dem Zeitleistenassistenten verwendet werden, um die Ausgabe animiert zu demonstrieren. Darüber hinaus bietet Xcode Debugging-Funktionen für die Swift-Entwicklung, einschließlich Breakpoints, Step-Through- und Step-Over-Anweisungen sowie Aufschlüsselungen der Platzierung von UI-Elementen für App-Entwickler.

Apple sagt, dass Swift "eine Programmiersprache in Industriequalität ist, die so ausdrucksstark und unterhaltsam ist wie eine Skriptsprache".

Leistung

Viele der mit Swift eingeführten Funktionen weisen bekannte Kompromisse bei Leistung und Sicherheit auf. Apple hat Optimierungen implementiert , die diesen Overhead reduzieren.

Vergleiche mit anderen Sprachen

Swift gilt als Programmiersprache der C-Familie und ähnelt C in vielerlei Hinsicht:

  • Die meisten C-Operatoren werden in Swift verwendet, es gibt jedoch einige neue Operatoren, um beispielsweise Integer-Operationen mit Überlauf zu unterstützen (siehe unter Unterschiede).
  • Geschweifte Klammern werden verwendet, um Anweisungen zu gruppieren.
  • Variablen werden mit einem Gleichheitszeichen zugewiesen , aber mit zwei aufeinanderfolgenden Gleichheitszeichen verglichen . Ein neuer Identitätsoperator === wird bereitgestellt, um zu überprüfen, ob zwei Datenelemente auf dasselbe Objekt verweisen .
  • Steueranweisungen while, ifund switchsind ähnlich, aber haben Funktionen erweitert, beispielsweise eine , switchdie nicht-ganzzahlige Fälle nimmt, whileund Stützmustervergleichif und bedingt optionals, Auswickeln verwendet die Syntax.forfor i in 1...10
  • Eckige Klammern werden bei Arrays verwendet , um sie zu deklarieren und um einen Wert an einem bestimmten Index in einem von ihnen zu erhalten.

Es hat auch Ähnlichkeiten mit Objective-C:

  • Grundlegende numerische Typen ( Int, UInt, Float, Double)
  • Klassenmethoden werden wie Instanzmethoden vererbt; selfin Klassenmethoden ist die Klasse, für die die Methode aufgerufen wurde.
  • Ähnliche for... inAufzählungssyntax.

Unterschiede zu Objective-C umfassen:

  • Anweisungen müssen nicht mit Semikolons ( ;) enden , diese müssen jedoch verwendet werden, um mehr als eine Anweisung in einer Zeile zuzulassen.
  • Keine Header-Dateien.
  • Verwendet Typinferenz .
  • Generische Programmierung .
  • Funktionen sind erstklassige Objekte.
  • Aufzählungsfälle können verknüpfte Daten ( algebraische Datentypen ) haben.
  • Für Klassen können Operatoren neu definiert werden ( Operatorüberladung ) und neue Operatoren können definiert werden.
  • Strings unterstützen Unicode vollständig . Die meisten Unicode-Zeichen können entweder in Bezeichnern oder Operatoren verwendet werden.
  • Keine Ausnahmebehandlung . Swift 2 führt ein anderes und inkompatibles Fehlerbehandlungsmodell ein.
  • Mehrere leicht zu missbrauchende Funktionen früherer Sprachen der C-Familie wurden entfernt:
    • Zeiger werden standardmäßig nicht verfügbar gemacht. Es besteht keine Notwendigkeit für den Programmierer, Namen für die Referenzierung oder Dereferenzierung zu verfolgen und zu markieren.
    • Zuweisungen geben keinen Wert zurück. Dies verhindert den üblichen Schreibfehler, i = 0anstatt i == 0einen Kompilierzeitfehler auszulösen.
    • Es müssen keine breakAnweisungen in switchBlöcken verwendet werden. Einzelne Fälle fallen nicht auf den nächsten Fall durch, es sei denn, die fallthroughAnweisung wird verwendet.
    • Variablen und Konstanten werden immer initialisiert und Arraygrenzen werden immer überprüft.
    • Ganzzahlüberläufe , die in C zu undefiniertem Verhalten für vorzeichenbehaftete Ganzzahlen führen, werden in Swift als Laufzeitfehler abgefangen. Programmierer können Überläufe zulassen, indem sie die speziellen arithmetischen Operatoren &+, &-, &*, &/und verwenden &%. Die Eigenschaften minund maxwerden in Swift für alle Integer-Typen definiert und können verwendet werden, um sicher auf potenzielle Überläufe zu prüfen, anstatt sich auf Konstanten zu verlassen, die für jeden Typ in externen Bibliotheken definiert sind.
    • Die Ein-Statement-Form von ifund while, die das Weglassen von geschweiften Klammern um die Anweisung erlaubt, wird nicht unterstützt.
    • Enumeration im C-Stil for (int i = 0; i < c; i++), die anfällig für Einzelfehler ist , wird nicht unterstützt (ab Swift 3).
    • Die Prä- und Post- Inkrement- und Dekrement-Operatoren ( i++, --i...) werden nicht unterstützt (ab Swift 3), zumal auch C- forAnweisungen ab Swift 3 nicht unterstützt werden.

Entwicklung und andere Implementierungen

Da die Sprache Open Source ist, besteht die Möglichkeit, dass sie ins Web portiert wird. Einige Web - Frameworks sind bereits entwickelt worden, wie zum Beispiel IBM ‚s Kitura , Perfekt und Dampf .

Auch eine offizielle Arbeitsgruppe "Server APIs" wurde von Apple ins Leben gerufen, in der Mitglieder der Swift-Entwickler-Community eine zentrale Rolle spielen.

Eine zweite freie Implementierung von Swift , dass die Ziele Cocoa , Microsoft ‚s Common Language Infrastructure ( .NET ) und die Java und Android - Plattform existiert als Teil des Elements Compiler von RemObjects .

Durch die Kombination von Toolchains von LLVM und Macintosh Programmer's Workshop ist es möglich, einen sehr kleinen Teil der Sprache unter Mac OS 9 auszuführen .

Siehe auch

Verweise

Externe Links