Swift (langage de programmation) - Swift (programming language)

Rapide
Swift logo.svg
Logo
Paradigme Multi-paradigme : orienté protocole , orienté objet , fonctionnel , impératif , structuré par blocs , déclaratif
Conçu par Chris Lattner , Doug Gregor, John McCall, Ted Kremenek, Joe Groff et Apple Inc.
Développeur Apple Inc. et les contributeurs open source
Première apparition 2 juin 2014 ; Il y a 7 ans ( 02/06/2014 )
Version stable
5.4.2  Modifiez ceci sur Wikidata / 28 juin 2021 ; il y a 3 mois ( 28 juin 2021 )
Version préliminaire
5.5 branche
Discipline de frappe Statique , fort , inféré
Système d'exploitation Systèmes d'exploitation d'Apple ( Darwin , iOS , iPadOS , macOS , tvOS , watchOS ), Linux , Windows 10 , Android
Licence Licence Apache 2.0 (Swift 2.2 et versions ultérieures)
Propriétaire (jusqu'à Swift 2.2)
Extensions de nom de fichier .swift, .SWIFT
Site Internet rapide .org
Influencé par
Objective-C , Rust , Haskell , Ruby , Python , C# , CLU , D
Influencé
Rouiller

Swift est un langage de programmation compilé à usage général , multi-paradigmes , développé par Apple Inc. et la communauté open source . Lancé pour la première fois en 2014, Swift a été développé pour remplacer le langage de programmation précédent d'Apple Objective-C , car Objective-C était resté en grande partie inchangé depuis le début des années 1980 et manquait de fonctionnalités de langage moderne. Swift fonctionne avec les frameworks Cocoa et Cocoa Touch d'Apple , et un aspect clé de la conception de Swift était la capacité d'interagir avec l'énorme corpus de code Objective-C existant développé pour les produits Apple au cours des décennies précédentes. Il est construit avec le framework de compilateur open source LLVM et est inclus dans Xcode depuis la version 6, sortie en 2014. Sur les plates-formes Apple, il utilise la bibliothèque d'exécution Objective-C , qui permet au code C , Objective-C , C++ et Swift de exécuter dans un seul programme.

Apple voulait que Swift prenne en charge de nombreux concepts de base associés à Objective-C , notamment la répartition dynamique , la liaison tardive généralisée , la programmation extensible et des fonctionnalités similaires, mais d'une manière "plus sûre", facilitant la détection des bogues logiciels ; Swift a des fonctionnalités qui corrigent certaines erreurs de programmation courantes comme le déréférencement de pointeur nul et fournit du sucre syntaxique pour aider à éviter la pyramide du destin . Swift prend en charge le concept d' extensibilité de protocole , un système d'extensibilité qui peut être appliqué aux types, aux structures et aux classes , qu'Apple promeut comme un véritable changement dans les paradigmes de programmation qu'ils appellent "programmation orientée protocole" (similaire aux traits ).

Swift a été présenté lors de la conférence mondiale des développeurs (WWDC) d' Apple en 2014 . Il a subi une mise à niveau vers la version 1.2 en 2014 et une mise à niveau majeure vers Swift 2 lors de la WWDC 2015. Initialement un langage propriétaire , la version 2.2 est devenue un logiciel open source sous la licence Apache 2.0 le 3 décembre 2015, pour les plates-formes Apple et Linux .

Grâce à la version 3.0, la syntaxe de Swift a connu une évolution significative, l'équipe principale faisant de la stabilité des sources un objectif dans les versions ultérieures. Au premier trimestre de 2018, Swift a dépassé Objective-C en termes de popularité mesurée.

Swift 4.0, publié en 2017, a introduit plusieurs modifications dans certaines classes et structures intégrées. Le code écrit avec les versions précédentes de Swift peut être mis à jour à l'aide de la fonctionnalité de migration intégrée à Xcode. Swift 5, sorti en mars 2019, a introduit une interface binaire stable sur les plates-formes Apple, permettant à l'environnement d'exécution Swift d'être intégré aux systèmes d'exploitation Apple. Il est compatible avec Swift 4.

Swift 5.1 a été officiellement publié en septembre 2019. Swift 5.1 s'appuie sur la version précédente de Swift 5 en étendant les fonctionnalités stables du langage au moment de la compilation avec l'introduction de la stabilité du module. L'introduction de la stabilité des modules permet de créer et de partager des frameworks binaires qui fonctionneront avec les futures versions de Swift.

Swift 5.5, officiellement annoncé par Apple lors de la WWDC 2021 , étend considérablement la prise en charge du langage pour la concurrence et le code asynchrone , introduisant notamment une version unique du modèle d'acteur .

Histoire

Le développement de Swift a commencé en juillet 2010 par Chris Lattner , avec la collaboration éventuelle de nombreux autres programmeurs d' Apple . Swift a pris des idées de langage "d' Objective-C , Rust , Haskell , Ruby , Python , C# , CLU et bien trop d'autres pour les énumérer ". Le 2 juin 2014, l'application Apple Worldwide Developers Conference (WWDC) est devenue la première application publique écrite avec Swift. Une version bêta du langage de programmation a été publiée pour les développeurs Apple enregistrés lors de la conférence, mais la société n'a pas promis que la version finale de Swift serait compatible avec le code source de la version de test. Apple prévoyait de rendre les convertisseurs de code source disponibles si nécessaire pour la version complète.

Le Swift Programming Language , un manuel gratuit de 500 pages, a également été publié à la WWDC et est disponible sur l' Apple Books Store et le site officiel.

Swift a atteint le jalon 1.0 le 9 septembre 2014, avec le Gold Master de Xcode 6.0 pour iOS . Swift 1.1 est sorti le 22 octobre 2014, parallèlement au lancement de Xcode 6.1. Swift 1.2 est sorti le 8 avril 2015, avec Xcode 6.3. Swift 2.0 a été annoncé à la WWDC 2015 et a été rendu disponible pour la publication d'applications dans l'App Store le 21 septembre 2015. Swift 3.0 a été publié le 13 septembre 2016. Swift 4.0 a été publié le 19 septembre 2017. Swift 4.1 a été publié le 29 mars 2018.

Swift a remporté la première place du langage de programmation le plus apprécié dans le Stack Overflow Developer Survey 2015 et la deuxième place en 2016.

Le 3 décembre 2015, le langage Swift, les bibliothèques de support, le débogueur et le gestionnaire de packages ont été ouverts sous la licence Apache 2.0 avec une exception de bibliothèque d'exécution, et Swift.org a été créé pour héberger le projet. Le code source est hébergé sur GitHub , où il est facile pour n'importe qui d'obtenir le code, de le créer lui-même et même de créer des demandes d'extraction pour contribuer au code du projet.

En décembre 2015, IBM a annoncé son site Web Swift Sandbox, qui permet aux développeurs d'écrire du code Swift dans un volet et d'afficher la sortie dans un autre. Le Swift Sandbox a été déprécié en janvier 2018.

Au cours de la WWDC 2016 , Apple a annoncé un iPad exclusif application , appelée Swift Playgrounds , destiné aux gens d'apprendre comment code Swift. L'application est présentée dans une interface de type jeu vidéo 3D qui fournit des informations lorsque des lignes de code sont placées dans un certain ordre et exécutées.

En janvier 2017, Chris Lattner a annoncé son départ d'Apple pour un nouveau poste chez Tesla Motors , le rôle de chef de projet Swift revenant au vétéran de l'équipe Ted Kremenek.

Au cours de la WWDC 2019, Apple a annoncé SwiftUI avec Xcode 11, qui fournit un cadre pour la conception de structure d'interface utilisateur déclarative sur toutes les plates-formes Apple.

Les téléchargements officiels pour la distribution Ubuntu de Linux sont disponibles depuis Swift 2.2, avec plus de distributions ajoutées depuis Swift 5.2.4, CentOS et Amazon Linux. Il existe également un SDK non officiel et un package de chaîne d'outils natif pour Android.

Plateformes

Les plates-formes prises en charge par Swift sont les systèmes d'exploitation d'Apple ( Darwin , iOS , iPadOS , macOS , tvOS , watchOS ), Linux , Windows et Android .

Historique des versions

Version Date de sortie macOS Linux les fenêtres
Rapide 1.0 9 septembre 2014 Oui Non Non
Rapide 1.1 22 octobre 2014 Oui Non Non
Rapide 1.2 8 avril 2015 Oui Non Non
Rapide 2.0 21 septembre 2015 Oui Non Non
Rapide 2.1 20 octobre 2015 Oui Non Non
Rapide 2.2 21 mars 2016 Oui Oui Non
Rapide 2.2.1 3 mai 2016 Oui Oui Non
Rapide 3.0 13 septembre 2016 Oui Oui Non
Rapide 3.0.1 28 octobre 2016 Oui Oui Non
Rapide 3.0.2 13 décembre 2016 Oui Oui Non
Rapide 3.1 27 mars 2017 Oui Oui Non
Rapide 3.1.1 21 avril 2017 Oui Oui Non
Rapide 4.0 19 septembre 2017 Oui Oui Non
Rapide 4.0.2 1er novembre 2017 Oui Oui Non
Rapide 4.0.3 5 décembre 2017 Oui Oui Non
Rapide 4.1 29 mars 2018 Oui Oui Non
Rapide 4.1.1 4 mai 2018 Non Oui Non
Rapide 4.1.2 31 mai 2018 Oui Oui Non
Rapide 4.1.3 27 juillet 2018 Non Oui Non
Rapide 4.2 17 septembre 2018 Oui Oui Non
Rapide 4.2.1 30 octobre 2018 Oui Oui Non
Rapide 4.2.2 4 février 2019 Non Oui Non
Rapide 4.2.3 28 février 2019 Non Oui Non
Rapide 4.2.4 29 mars 2019 Non Oui Non
Rapide 5.0 25 mars 2019 Oui Oui Non
Rapide 5.0.1 18 avril 2019 Oui Oui Non
Rapide 5.0.2 15 juillet 2019 Non Oui Non
Rapide 5.0.3 30 août 2019 Non Oui Non
Rapide 5.1 10 septembre 2019 Oui Oui Non
Rapide 5.1.1 11 octobre 2019 Non Oui Non
Rapide 5.1.2 7 novembre 2019 Oui Oui Non
Rapide 5.1.3 13 décembre 2019 Oui Oui Non
Rapide 5.1.4 31 janvier 2020 Non Oui Non
Rapide 5.1.5 9 mars 2020 Non Oui Non
Rapide 5.2 24 mars 2020 Oui Oui Non
Rapide 5.2.1 30 mars 2020 Non Oui Non
Rapide 5.2.2 15 avril 2020 Oui Oui Non
Rapide 5.2.3 29 avril 2020 Non Oui Non
Rapide 5.2.4 20 mai 2020 Oui Oui Non
Rapide 5.2.5 5 août 2020 Non Oui Non
Rapide 5.3 16 septembre 2020 Oui Oui Oui
Rapide 5.3.1 13 novembre 2020 Oui Oui Oui
Rapide 5.3.2 15 décembre 2020 Oui Oui Oui
Rapide 5.3.3 25 janvier 2021 Non Oui Oui
Rapide 5.4 26 avril 2021 Oui Oui Oui
Rapide 5.4.1 25 mai 2021 Non Oui Oui
Rapide 5.4.2 28 juin 2021 Oui Oui Oui
Rapide 5.4.3 9 septembre 2021 Non Oui Oui
Rapide 5.5 20 septembre 2021 Oui Oui Oui

Caractéristiques

Swift est une alternative au langage Objective-C qui utilise les concepts de la théorie du langage de programmation moderne et s'efforce de présenter une syntaxe plus simple. Lors de son introduction, il a été décrit simplement comme "Objectif-C sans les bagages de C".

Par défaut, Swift n'expose pas les pointeurs et autres accesseurs non sécurisés , contrairement à Objective-C, qui utilise des pointeurs de manière omniprésente pour faire référence à des instances d'objets. En outre, l'utilisation par Objective-C d'une syntaxe de type Smalltalk pour effectuer des appels de méthode a été remplacée par un style de notation par points et un système d' espace de noms plus familiers aux programmeurs d'autres langages orientés objet (OO) courants comme Java ou C# . Swift introduit de vrais paramètres nommés et conserve les concepts clés Objective-C, y compris les protocoles , les fermetures et les catégories , remplaçant souvent l'ancienne syntaxe par des versions plus propres et permettant à ces concepts d'être appliqués à d'autres structures de langage, comme les types énumérés ( énumérations ).

Support de fermeture

Swift prend en charge les fermetures (appelées lambdas dans d'autres langues). Les fermetures sont des blocs de fonctionnalités autonomes qui peuvent être transmis et utilisés dans votre code. Les fermetures peuvent être considérées comme une fonction sans nom. Voici un exemple:

// 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 a une syntaxe de fermeture de fin comme celle-ci :

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

À partir de la version 5.3, Swift prend en charge plusieurs fermetures de fin :

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

Voici les critères de la syntaxe de fermeture de fin :

  • Si les derniers arguments d'une fonction sont des fermetures, vous pouvez utiliser la syntaxe de fermeture de fin.
  • Le nom du paramètre de la première fermeture de fin doit être omis.
  • Les noms de paramètre des fermetures de fin restantes ne doivent pas être omis.
  • Si tous les arguments donnés à une fonction sont des fermetures de fin, vous pouvez omettre les parenthèses après le nom de la fonction.
  • Les appels à une fonction avec des fermetures de fin doivent être entre parenthèses s'ils sont utilisés dans une guardinstruction.

Prise en charge des chaînes

Dans les environnements Cocoa et Cocoa Touch , de nombreuses classes communes faisaient partie de la bibliothèque Foundation Kit . Cela comprenait la bibliothèque de chaînes NSString (utilisant Unicode , UTF-8 dans Swift 5, modifié par rapport à UTF-16 ), les classes de collection NSArray et NSDictionary, et d'autres. Objective-C a fourni divers morceaux de sucre syntaxique pour permettre à certains de ces objets d'être créés à la volée dans le langage, mais une fois créés, les objets ont été manipulés avec des appels d'objet. Par exemple, en Objective-C, la concaténation de deux NSStrings requiert des appels de méthode similaires à celui-ci :

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

Dans Swift, bon nombre de ces types de base ont été promus au cœur du langage et peuvent être manipulés directement. Par exemple, les chaînes sont invisiblement liées à NSString (lorsque Foundation est importée) et peuvent désormais être concaténées avec l' +opérateur, ce qui permet une syntaxe grandement simplifiée ; l'exemple précédent devenant :

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

Contrôle d'accès

Swift soutient cinq contrôle d'accès des niveaux pour les symboles: open, public, internal, fileprivateet private. Contrairement à de nombreux langages orientés objet, ces contrôles d'accès ignorent les hiérarchies d' héritage : privateindique qu'un symbole n'est accessible que dans la portée immédiate , fileprivateindique qu'il est accessible uniquement à partir du fichier, internalindique qu'il est accessible dans le module conteneur, publicindique qu'il est accessible à partir de n'importe quel module, et open(uniquement pour les classes et leurs méthodes) indique que la classe peut être sous-classée en dehors du module.

Options et chaînage

Une nouvelle fonctionnalité importante dans Swift est les types d'options , qui permettent aux références ou aux valeurs de fonctionner d'une manière similaire au modèle commun dans C , où un pointeur peut faire référence à une valeur ou peut être null. Cela implique que les types non facultatifs ne peuvent pas entraîner d' erreur de pointeur nul ; le compilateur peut s'assurer que ce n'est pas possible.

Les types facultatifs sont créés avec le Optionalmécanisme : pour créer un entier qui est nullable, on utiliserait une déclaration similaire à var optionalInteger: Optional<Int>. Comme en C#, Swift inclut également du sucre syntaxique pour cela, permettant d'indiquer qu'une variable est facultative en plaçant un point d'interrogation après le nom du type, var optionalInteger: Int?. Les variables ou les constantes marquées comme facultatives ont une valeur du type sous-jacent ou sont nil. Les types facultatifs enveloppent le type de base, ce qui donne une instance différente. Stringet String?sont des types fondamentalement différents, ce dernier a plus en commun avec Int?que String.

Pour accéder à la valeur à l'intérieur, en supposant qu'elle n'est pas nulle, elle doit être déballée pour exposer l'instance à l'intérieur. Ceci est effectué avec l' !opérateur :

let myValue = anOptionalInstance!.someMethod()

Dans ce cas, l' !opérateur se déroule anOptionalInstancepour exposer l'instance à l'intérieur, permettant à l'appel de méthode d'être effectué dessus. Si anOptionalInstanceest nul, une erreur de pointeur nul se produit. Cela peut être ennuyeux dans la pratique, donc Swift inclut également le concept de chaînage facultatif pour tester si l'instance est nil, puis la déballer si elle n'est pas null :

let myValue = anOptionalInstance?.someMethod()

Dans ce cas, le runtime n'appelle someMethodque si anOptionalInstancen'est pas nul, supprimant l'erreur. Normalement, cela nécessite que le programmeur teste si myValuec'est nil avant de continuer. L'origine du terme chaînage vient du cas le plus courant où plusieurs appels/getters de méthode sont chaînés ensemble. Par exemple:

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

peut être réduit à :

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

La ?syntaxe contourne la pyramide du destin .

Swift 2 a introduit le nouveau mot-clé guardpour les cas dans lesquels le code doit cesser de s'exécuter si une condition n'est pas remplie :

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

L'utilisation guarda trois avantages. Bien que la syntaxe puisse agir comme une ifinstruction, son principal avantage est de déduire la non-nullabilité. Lorsqu'une ifdéclaration requiert un cas, guardassume le cas en fonction de la condition fournie. De plus, puisque guardne contient aucune portée, à l'exception de la elsefermeture, leaseStartest présenté comme une option non emballée pour la super-portée de la garde. Enfin, si le guardtest de l' instruction échoue, Swift exige elsede quitter la méthode ou la boucle actuelle, en s'assurant que l'on leaseStartn'y accède jamais lorsque nil. Ceci est effectué avec les mots-clés return, continue, break, ou throw, ou en appelant une fonction renvoyant un Never(par exemple fatalError()).

Objective-C était faiblement typé et permettait d'appeler n'importe quelle méthode sur n'importe quel objet à tout moment. Si l'appel de méthode échouait, il y avait un gestionnaire par défaut dans l'environnement d'exécution qui renvoyait nil. Cela signifiait qu'aucun déballage ou test n'était nécessaire, la déclaration équivalente en Objective-C :

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

Reviendrait nul, et cela pourrait être testé. Cependant, cela exigeait également que tous les appels de méthode soient dynamiques, ce qui introduit une surcharge importante. L'utilisation d'options par Swift fournit un mécanisme similaire pour tester et traiter les nils, mais le fait d'une manière qui permet au compilateur d'utiliser la répartition statique car l'action de dépliage est appelée sur une instance définie (le wrapper), au lieu de se produire dans la répartition d'exécution système.

Types de valeur

Dans de nombreux langages orientés objet, les objets sont représentés en interne en deux parties. L'objet est stocké sous la forme d'un bloc de données placé sur le tas , tandis que le nom (ou "handle") de cet objet est représenté par un pointeur . Les objets sont passés entre les méthodes en copiant la valeur du pointeur, permettant aux mêmes données sous-jacentes sur le tas d'être accessibles par toute personne disposant d'une copie. En revanche, les types de base comme les entiers et les valeurs à virgule flottante sont représentés directement ; le handle contient les données, pas un pointeur vers elles, et ces données sont transmises directement aux méthodes par copie. Ces styles d'accès sont appelés passage par référence dans le cas des objets, et passage par valeur pour les types de base.

Les deux concepts ont leurs avantages et leurs inconvénients. Les objets sont utiles lorsque les données sont volumineuses, comme la description d'une fenêtre ou le contenu d'un document. Dans ces cas, l'accès à ces données est fourni en copiant une valeur de 32 ou 64 bits, au lieu de copier une structure de données entière. Cependant, les valeurs plus petites comme les entiers ont la même taille que les pointeurs (généralement les deux sont un mot ), il n'y a donc aucun avantage à passer un pointeur par rapport à passer la valeur. En outre, le passage par référence nécessite intrinsèquement une opération de déréférencement, qui peut produire une surcharge notable dans certaines opérations, généralement celles utilisées avec ces types de valeur de base, comme les mathématiques.

De la même manière que C# et contrairement à la plupart des autres langages OO, Swift offre une prise en charge intégrée des objets utilisant la sémantique de passage par référence ou de passage par valeur, le premier utilisant la classdéclaration et le second utilisant struct. Les structures dans Swift ont presque toutes les mêmes fonctionnalités que les classes : méthodes, implémentation de protocoles et utilisation des mécanismes d'extension. Pour cette raison, Apple qualifie génériquement toutes les données d' instances , par opposition à des objets ou des valeurs. Cependant, les structures ne prennent pas en charge l'héritage.

Le programmeur est libre de choisir la sémantique la plus appropriée pour chaque structure de données de l'application. Les structures plus grandes comme les fenêtres seraient définies comme des classes, ce qui leur permettrait d'être transmises comme des pointeurs. Des structures plus petites, comme un point 2D, peuvent être définies comme des structures, qui seront transmises par valeur et permettront un accès direct à leurs données internes sans déréférencement. L'amélioration des performances inhérente au concept de passage par valeur est telle que Swift utilise ces types pour presque tous les types de données courants, y compris Intet Double, et les types normalement représentés par des objets, comme Stringet Array. L'utilisation de types valeur peut également entraîner des améliorations significatives des performances dans les applications utilisateur.

Pour s'assurer que même les structures les plus volumineuses ne causent pas de perte de performances lorsqu'elles sont transférées, Swift utilise la copie sur écriture afin que les objets ne soient copiés que si et lorsque le programme tente de modifier une valeur en eux. Cela signifie que les divers accesseurs ont ce qui est en fait un pointeur vers le même stockage de données. Ainsi, alors que les données sont physiquement stockées en tant qu'instance en mémoire, au niveau de l'application, ces valeurs sont distinctes et la séparation physique est appliquée par copie sur écriture uniquement si nécessaire.

Programmation orientée protocole

Une caractéristique clé d'Objective-C est sa prise en charge des catégories , des méthodes qui peuvent être ajoutées pour étendre les classes au moment de l'exécution. Les catégories permettent d'étendre les classes sur place pour ajouter de nouvelles fonctions sans avoir besoin de sous-classer ou même d'avoir accès au code source d' origine . Un exemple pourrait être d'ajouter la prise en charge du correcteur orthographique à la NSStringclasse de base , ce qui signifie que toutes les instances de NSString dans l'application bénéficient d'un correcteur orthographique. Le système est également largement utilisé comme technique d'organisation, permettant de rassembler le code associé dans des extensions de type bibliothèque. Swift continue de prendre en charge ce concept, bien qu'elles soient désormais appelées extensions , et déclarées avec le mot-clé extension. Contrairement à Objective-C, Swift peut également ajouter de nouveaux accesseurs de propriétés, types et énumérations aux instances existantes.

Une autre caractéristique clé d'Objective-C est son utilisation de protocoles , connus dans la plupart des langages modernes sous le nom d' interfaces . Les protocoles promettent qu'une classe particulière implémente un ensemble de méthodes, ce qui signifie que d'autres objets du système peuvent appeler ces méthodes sur n'importe quel objet prenant en charge ce protocole. Ceci est souvent utilisé dans les langages OO modernes comme substitut à l' héritage multiple , bien que les ensembles de fonctionnalités ne soient pas entièrement similaires. Un exemple courant de protocole dans Cocoa est le NSCopyingprotocole, qui définit une méthode, copyWithZone, qui implémente la copie en profondeur sur les objets.

En Objective-C, et dans la plupart des autres langages implémentant le concept de protocole, il appartient au programmeur de s'assurer que les méthodes requises sont implémentées dans chaque classe. Swift ajoute la possibilité d'ajouter ces méthodes à l'aide d'extensions et d'utiliser une programmation générique (génériques) pour les implémenter. Combinés, ceux-ci permettent aux protocoles d'être écrits une seule fois et prennent en charge une grande variété d'instances. En outre, le mécanisme d'extension peut être utilisé pour ajouter une conformité de protocole à un objet qui ne répertorie pas ce protocole dans sa définition.

Par exemple, un protocole peut être déclaré appelé StringConvertible, ce qui garantit que les instances conformes au protocole implémentent une toStringméthode qui renvoie un String. Dans Swift, cela peut être déclaré avec un code comme celui-ci :

protocol StringConvertible
{
    func toString() -> String
}

Ce protocole peut maintenant être ajouté à String, sans accès à la source de la classe de base :

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

Dans Swift, comme de nombreux langages modernes prenant en charge les interfaces, les protocoles peuvent être utilisés comme types, ce qui signifie que les variables et les méthodes peuvent être définies par protocole au lieu de leur type spécifique :

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

Peu importe le type d'instance someSortOfPrintableObject, le compilateur s'assurera qu'elle est conforme au protocole et donc ce code est sûr. Cette syntaxe signifie également que les collections peuvent également être basées sur des protocoles, comme let printableArray = [StringConvertible].

Comme Swift traite les structures et les classes comme des concepts similaires, les extensions et les protocoles sont largement utilisés dans l'environnement d'exécution de Swift pour fournir une API riche basée sur les structures. Par exemple, Swift utilise une extension pour ajouter le Equatableprotocole à bon nombre de leurs types de base, comme les chaînes et les tableaux, ce qui leur permet d'être comparés à l' ==opérateur. Un exemple concret de la façon dont toutes ces fonctionnalités interagissent peut être vu dans le concept d' implémentations de protocole par défaut :

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

Cette fonction définit une méthode qui fonctionne sur toute instance conforme à Equatable, en fournissant une égale pas la fonction. Toute instance, classe ou struct, obtient automatiquement cette implémentation simplement en se conformant à Equatable. Comme de nombreuses instances gagnent Equatablegrâce à leurs implémentations de base ou à d'autres extensions génériques, la plupart des objets de base dans l'environnement d'exécution sont égaux et non égaux sans code.

Cette combinaison de protocoles, de valeurs par défaut, d'héritage de protocole et d'extensions permet à de nombreuses fonctions normalement associées aux classes et à l'héritage d'être implémentées sur des types valeur. Correctement utilisé, cela peut conduire à des améliorations de performances spectaculaires sans aucune limite significative dans l'API. Ce concept est si largement utilisé au sein de Swift qu'Apple a commencé à l'appeler un langage de programmation orienté protocole . Ils suggèrent d'aborder de nombreux domaines de problèmes normalement résolus par les classes et l'héritage en utilisant à la place des protocoles et des structures.

Bibliothèques, runtime et développement

Sur les systèmes Apple, Swift utilise le même temps d'exécution que le système Objective-C existant, mais nécessite iOS 7 ou macOS 10.9 ou supérieur. Cela dépend aussi de Grand Central Dispatch . Le code Swift et Objective-C peut être utilisé dans un seul programme, et par extension, C et C++ également. Contrairement au C, le code C++ ne peut pas être utilisé directement depuis Swift. Un wrapper Objective-C ou C doit être créé entre Swift et C++. Dans le cas d'Objective-C, Swift a un accès considérable au modèle objet et peut être utilisé pour sous-classer, étendre et utiliser le code Objective-C pour fournir un support de protocole. L'inverse n'est pas vrai : une classe Swift ne peut pas être sous-classée en Objective-C.

Pour faciliter le développement de tels programmes et la réutilisation du code existant, Xcode 6 et versions ultérieures offrent un système semi-automatisé qui crée et maintient un en- tête de pontage pour exposer le code Objective-C à Swift. Cela prend la forme d'un fichier d'en-tête supplémentaire qui définit ou importe simplement tous les symboles Objective-C nécessaires au code Swift du projet. À ce stade, Swift peut faire référence aux types, fonctions et variables déclarés dans ces importations comme s'ils étaient écrits en Swift. Le code Objective-C peut également utiliser directement le code Swift, en important un fichier d'en-tête géré automatiquement avec les déclarations Objective-C des symboles Swift du projet. Par exemple, un fichier Objective-C dans un projet mixte appelé "MyApp" pourrait accéder aux classes ou fonctions Swift avec le code #import "MyApp-Swift.h". Cependant, tous les symboles ne sont pas disponibles via ce mécanisme - l'utilisation de fonctionnalités spécifiques à Swift comme les types génériques, les types facultatifs non-objet, les énumérations sophistiquées ou même les identifiants Unicode peuvent rendre un symbole inaccessible depuis Objective-C.

Swift a également une prise en charge limitée des attributs , des métadonnées qui sont lues par l'environnement de développement et ne font pas nécessairement partie du code compilé. Comme Objective-C, les attributs utilisent la @syntaxe, mais l'ensemble actuellement disponible est petit. Un exemple est l' @IBOutletattribut, qui marque une valeur donnée dans le code en tant que point de vente , disponible pour une utilisation dans Interface Builder (IB). Une prise est un appareil qui lie la valeur de l'affichage à l'écran à un objet dans le code.

Sur les systèmes non Apple, Swift ne dépend pas d'un runtime Objective-C ou d'autres bibliothèques système Apple ; un ensemble d'implémentations Swift "Corelib" les remplace. Ceux-ci incluent un "swift-corelibs-foundation" pour remplacer le kit de fondation , un "swift-corelibs-libdispatch" pour remplacer le Grand Central Dispatch et un "swift-corelibs-xctest" pour remplacer le XCTest API de Xcode .

Depuis 2019, avec Xcode 11, Apple a également ajouté un nouveau paradigme d'interface utilisateur majeur appelé SwiftUI. SwiftUI remplace l'ancien paradigme Interface Builder par un nouveau paradigme de développement déclaratif.

Gestion de la mémoire

Swift utilise le comptage automatique de références (ARC) pour gérer la mémoire . Apple avait l'habitude d'exiger une gestion manuelle de la mémoire dans Objective-C, mais a introduit ARC en 2011 pour permettre une allocation et une désallocation de mémoire plus faciles. Un problème avec ARC est la possibilité de créer un cycle de référence fort , où les objets se référencent les uns les autres de manière à ce que vous puissiez atteindre l'objet de départ en suivant les références (par exemple A références B, B références A). Cela les fait fuir dans la mémoire car ils ne sont jamais libérés. Swift fournit les mots-clés weaket unownedpour éviter les cycles de référence forts. En règle générale, une relation parent-enfant utiliserait une référence forte tandis qu'un parent-enfant utiliserait l'une ou l'autre weakréférence, où les parents et les enfants peuvent être indépendants, ou unownedoù un enfant a toujours un parent, mais le parent peut ne pas avoir d'enfant. Les références faibles doivent être des variables facultatives, car elles peuvent changer et devenir nil.

Une fermeture au sein d'une classe peut également créer un cycle de référence fort en capturant des références à soi. Les références personnelles à traiter comme faibles ou sans propriétaire peuvent être indiquées à l'aide d'une liste de capture.

Débogage et autres éléments

Un élément clé du système Swift est sa capacité à être correctement débogué et exécuté dans l'environnement de développement, en utilisant une boucle de lecture-évaluation-impression (REPL), lui donnant des propriétés interactives plus en commun avec les capacités de script de Python que la programmation système traditionnelle . langues. Le REPL est encore amélioré avec des terrains de jeux , des vues interactives fonctionnant dans l'environnement Xcode qui répondent aux modifications de code ou de débogueur à la volée. Les terrains de jeux permettent aux programmeurs d'ajouter du code Swift avec la documentation de démarque. Si un code change au fil du temps ou par rapport à une autre valeur d'entrée à distance, la vue peut être utilisée avec l'assistant de chronologie pour montrer la sortie de manière animée. De plus, Xcode dispose de fonctionnalités de débogage pour le développement Swift, notamment des points d'arrêt, des instructions pas à pas et pas à pas, ainsi que des ventilations de placement d'éléments d'interface utilisateur pour les développeurs d'applications.

Apple dit que Swift est "un langage de programmation de qualité industrielle qui est aussi expressif et agréable qu'un langage de script".

Performance

De nombreuses fonctionnalités introduites avec Swift présentent des compromis bien connus en termes de performances et de sécurité. Apple a mis en place des optimisations qui réduisent cette surcharge.

Comparaisons avec d'autres langues

Swift est considéré comme un langage de programmation de la famille C et est similaire à C à plusieurs égards :

  • La plupart des opérateurs C sont utilisés dans Swift, mais il existe de nouveaux opérateurs, par exemple pour prendre en charge les opérations d'entier avec débordement (voir sous différences).
  • Les accolades sont utilisées pour regrouper les déclarations.
  • Les variables sont attribuées à l'aide d'un signe égal , mais comparées à l'aide de deux signes égal consécutifs . Un nouvel opérateur d'identité, ===, est fourni pour vérifier si deux éléments de données font référence au même objet .
  • Les instructions de contrôle while, if, et switchsont similaires, mais ont des fonctions étendues, par exemple a switchqui prend des cas non entiers whileet qui prend en ifcharge la correspondance de modèle et les options facultatives de dépliage conditionnel, forutilise la syntaxe.for i in 1...10
  • Les crochets sont utilisés avec les tableaux , à la fois pour les déclarer et pour obtenir une valeur à un indice donné dans l'un d'eux.

Il a également des similitudes avec Objective-C :

  • Types numériques de base ( Int, UInt, Float, Double)
  • Les méthodes de classe sont héritées, comme les méthodes d'instance ; selfdans les méthodes de classe est la classe sur laquelle la méthode a été appelée.
  • Similaire for... insyntaxe d'énumération.

Les différences par rapport à Objective-C incluent :

  • Les instructions n'ont pas besoin de se terminer par des points-virgules ( ;), bien que ceux-ci doivent être utilisés pour autoriser plusieurs instructions sur une ligne.
  • Aucun fichier d'en-tête.
  • Utilise l' inférence de type .
  • Programmation générique .
  • Les fonctions sont des objets de première classe .
  • Les cas d'énumération peuvent avoir des données associées ( types de données algébriques ).
  • Les opérateurs peuvent être redéfinis pour les classes ( surcharge d'opérateurs ), et de nouveaux opérateurs peuvent être définis.
  • Les chaînes prennent entièrement en charge Unicode . La plupart des caractères Unicode peuvent être utilisés dans les identificateurs ou les opérateurs.
  • Aucune gestion des exceptions . Swift 2 introduit un modèle de gestion des erreurs différent et incompatible.
  • Plusieurs fonctionnalités des langages antérieurs de la famille C qui sont faciles à mal utiliser ont été supprimées :
    • Les pointeurs ne sont pas exposés par défaut. Le programmeur n'a pas besoin de garder une trace et de marquer les noms pour référencement ou déréférencement.
    • Les affectations ne renvoient aucune valeur. Cela évite l'erreur courante d'écriture i = 0au lieu de i == 0lancer une erreur de compilation.
    • Pas besoin d'utiliser des breakinstructions dans les switchblocs. Les cas individuels ne passent pas au cas suivant à moins que l' fallthroughinstruction ne soit utilisée.
    • Les variables et les constantes sont toujours initialisées et les limites du tableau sont toujours vérifiées.
    • Les débordements d'entiers , qui entraînent un comportement indéfini pour les entiers signés en C, sont interceptés en tant qu'erreur d'exécution dans Swift. Les programmeurs peuvent choisir d'autoriser les dépassements à l'aide des opérateurs spéciaux arithmétiques &+, &-, &*, &/et &%. Les propriétés minet maxsont définies dans Swift pour tous les types d'entiers et peuvent être utilisées pour vérifier en toute sécurité les débordements potentiels, plutôt que de s'appuyer sur des constantes définies pour chaque type dans des bibliothèques externes.
    • La forme à une instruction de ifet while, qui permet d'omettre les accolades autour de l'instruction, n'est pas prise en charge.
    • L'énumération de style C for (int i = 0; i < c; i++), qui est sujette à des erreurs un par un , n'est pas prise en charge (à partir de Swift 3).
    • Les opérateurs pré et post-
    incrémentation et décrémentation ( i++, --i...) ne sont pas pris en charge (à partir de Swift 3), d'autant plus que les forinstructions de style C ne sont pas non plus prises en charge à partir de Swift 3.

Développement et autres implémentations

Étant donné que le langage est open-source, il est possible qu'il soit porté sur le Web. Certains cadres web ont déjà été développés, tels que IBM de Kitura , parfait et de vapeur .

Un groupe de travail officiel "Server APIs" a également été lancé par Apple, avec des membres de la communauté des développeurs Swift jouant un rôle central.

Une deuxième mise en œuvre libre de Swift que les objectifs de cacao , Microsoft de Common Language Infrastructure ( .NET ), et le Java et Android plate - forme existe dans le cadre du compilateur Les éléments de RemObjects Software .

En combinant les chaînes d' outils de LLVM et de Macintosh Programmer's Workshop , il est possible d'exécuter un très petit sous-ensemble du langage sur Mac OS 9 .

Voir également

Les références

Liens externes