Swift est un langage de programmation compilé de haut niveau, polyvalent et multi-paradigme, créé par Chris Lattner en 2010 pour Apple Inc. et maintenu par la communauté open-source. Swift se compile en code machine et utilise un compilateur basé sur LLVM. Swift a été publié pour la première fois en juin 2014 et la chaîne d'outils Swift est intégrée à Xcode depuis la version 6.
En 2020, l'équipe en charge du développement de Swift avait dévoilé la nouvelle feuille de route du projet vers la version 6. L'équipe de Swift a confirmé que Swift 6 est la prochaine itération majeure du langage après les versions 5.x. Swift 6 serait également plus axée sur le Machine Learning afin notamment de préparer l’intégration plus poussée de ce langage de programmation aux opérations en relation avec l’intelligence artificielle (IA), mais aussi "l'autonomisation de l’utilisateur".
Ce 17 Septembre, l'équipe de Swift vient d'annoncer la disponibilité générale de Swift 6. De nombreuses personnes connaissent Swift en tant que langage de développement d'applications, avec un million d'applications sur l'App Store. Mais Swift n'est pas seulement utile pour les applications. La sécurité, la vitesse et l'accessibilité de Swift en font un excellent choix pour de nombreux autres cas d'utilisation, notamment les bibliothèques, les services à l'échelle de l'internet et le code le plus critique en termes de performances et de sécurité.
Swift 6 va encore plus loin grâce à de nouvelles fonctionnalités de programmation de bas niveau, un sous-ensemble de langage Swift intégré, une prise en charge étendue de Linux et de Windows, de nouvelles API multiplateformes, notamment la nouvelle bibliothèque Swift Testing, et bien d'autres choses encore. Swift 6 apporte des changements au langage, aux bibliothèques standard, au débogage, à la prise en charge des plates-formes.
Voici quelques améliorations dans Swift 6 :
Concurrence
Swift offre depuis longtemps une sécurité de la mémoire, garantissant que les variables sont initialisées avant d'être utilisées, que la mémoire n'est pas accessible après avoir été désallouée et que les indices de tableau sont vérifiés pour les erreurs hors limites. Swift 6 inclut désormais un nouveau mode de langage optionnel qui étend les garanties de sécurité de Swift pour prévenir les courses de données dans le code concurrent en diagnostiquant les courses de données potentielles dans votre code comme des erreurs du compilateur.
Les contrôles de sécurité des courses de données (data-race) étaient auparavant disponibles sous forme d'avertissements dans Swift 5.10 grâce à l'option de compilation -strict-concurrency=complete. Grâce à l'amélioration de l'inférence Sendable et à la nouvelle analyse du compilateur pour le transfert d'un état mutable d'un acteur à un autre, les avertissements de Swift 6 concernant la sécurité des data-race ont moins de faux positifs.
Swift 6 marque le début d'un parcours visant à faciliter considérablement la sécurité des données. La facilité d'utilisation de la sécurité des données reste un domaine de développement actif pour le langage Swift.
Swift 6 s'accompagne également d'une nouvelle bibliothèque de synchronisation pour les API de concurrence de bas niveau, y compris les opérations atomiques et une nouvelle API mutex.
Fonctions typées "throws"
Swift 6 permet aux fonctions de spécifier le type d'erreur qu'elles lancent dans le cadre de leur signature. Cette fonctionnalité est utile dans le code générique qui transmet les erreurs lancées dans le code client, ou dans les environnements à ressources limitées qui ne peuvent pas allouer de mémoire, comme dans le code Swift intégré.
Exemple :
Code : | Sélectionner tout |
1 2 3 | func parseRecord(from string: String) throws(ParseError) -> Record { // ... } |
Code : | Sélectionner tout |
1 2 3 4 5 | do { let record = try parseRecord(from: myString) } catch { // 'error' has type 'ParseError' } |
Les fonctions typées "throws" peuvent également être utilisés dans les fonctions génériques pour propager les types d'erreur à partir des paramètres, d'une manière plus précise que les rethrows. Par exemple, la méthode Sequence.map peut propager le type d'erreur jeté à partir de son paramètre de fermeture, indiquant qu'elle ne jette que le même type d'erreurs que la fermeture :
Code : | Sélectionner tout |
1 2 3 4 5 | extension Sequence { func map<T, E>(_ body: (Element) throws(E) -> T) throws(E) -> [T] { // ... } } |
Propriété
Swift 5.9 a introduit les types non copiables avec la syntaxe ~Copyable pour modéliser les ressources avec une propriété unique, et écrire du code plus performant en éliminant la surcharge d'exécution associée à la copie. Swift 6 prend désormais en charge ces types avec le système générique, ce qui permet d'écrire du code générique qui fonctionne avec des types copiables et non copiables.
Exemple :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | protocol Drinkable: ~Copyable { consuming func use() } struct Coffee: Drinkable, ~Copyable { /* ... */ } struct Water: Drinkable { /* ... */ } func drink(item: consuming some Drinkable & ~Copyable) { item.use() } drink(item: Coffee()) drink(item: Water()) |
Il est désormais possible d'écrire des instructions de commutation pour éviter la copie dans les opérations de comparaison de motifs des enums. Cela signifie que les instructions switch peuvent être utilisées avec des données utiles non copiables et qu'elles peuvent également offrir des avantages en termes de performances pour les données utiles copiables, en particulier celles qui sont basées sur des conteneurs de copie en écriture comme Array et Dictionary.
Les types non copiables sont déjà utilisés dans les bibliothèques standard. Par exemple, le nouveau type Atomic de la bibliothèque Synchronisation est basé sur ~Copyable, Optional et Result peuvent désormais envelopper des types non copiables, et les types de pointeurs de tampons non sûrs peuvent désormais pointer vers des éléments non copiables. L'interopérabilité C++ utilise également des types non copiables pour exposer les types C++ à déplacement unique à Swift.
Interopérabilité C++
Swift 5.9 a introduit l'interopérabilité bidirectionnelle avec le C++ afin d'intégrer Swift à un plus grand nombre de projets existants. Swift 6 étend la prise en charge de l'interopérabilité aux types C++ à déplacement unique, aux méthodes virtuelles, aux arguments par défaut et à d'autres types de la bibliothèque standard, notamment std::map et std::optional.
Les types C++ qui n'ont pas de constructeur de copie sont désormais accessibles depuis Swift 6 en tant que types non copiables avec ~Copyable. Et pour les cas où il est utile d'exposer un type C++ avec un constructeur de copie en tant que ~Copyable dans Swift pour de meilleures performances, une nouvelle annotation SWIFT_NONCOPYABLE peut être appliquée au type C++.
Swift prend désormais également en charge les appels de méthodes virtuelles C++ sur les types annotés SWIFT_SHARED_REFERENCE ou SWIFT_IMMORTAL_REFERENCE.
Lors de l'appel de fonctions ou de méthodes C++ ayant des valeurs d'argument par défaut pour certains de leurs paramètres, Swift respecte désormais ces valeurs par défaut, au lieu de vous demander de passer explicitement un argument.
Swift embarqué
Swift 6 comprend un aperçu de "Swift embarqué" (Embedded Swift), un sous-ensemble de langage et un mode de compilation adaptés au développement de logiciels embarqués, tels que la programmation de microcontrôleurs. La chaîne d'outils prend en charge les cibles ARM et RISC-V bare-metal.
"Swift embarqué" produit de petits binaires autonomes en s'appuyant sur la spécialisation générique. Comme il ne s'appuie pas sur un runtime ou des métadonnées de type, "Swift embarqué" est adapté aux plates-formes à faibles contraintes de mémoire ainsi qu'à une utilisation dans des environnements de bas niveau avec des dépendances de runtime limitées.
"Swift embarqué" reste une fonctionnalité expérimentale, en cours de développement avant une prise en charge stable dans une prochaine version de Swift.
Intégration 128 bits
Swift 6 complète l'ensemble des primitives entières de bas niveau avec l'ajout de types d'entiers signés et non signés de 128 bits. Ceux-ci sont disponibles sur toutes les plateformes Swift et fournissent la même API que les autres types d'entiers à largeur fixe de la bibliothèque standard.
Améliorations de la productivité
Swift 6 introduit un certain nombre d'améliorations de la productivité, notamment count(where pour rationaliser le comptage du nombre d'éléments d'une séquence qui satisfont un prédicat, "pack iteration" pour écrire des boucles for naturelles sur les éléments d'un pack de paramètres de valeur, contrôle d'accès pour les importations afin d'empêcher les détails de l'implémentation de fuir dans vos API publiques, macros @attached(body) pour synthétiser et augmenter les implémentations de fonctions, macros d'expression en tant qu'arguments par défaut, et bien plus encore.
Amélioration des performances de démarrage avec les modules explicites
Swift 6 améliore considérablement les performances de démarrage du débogueur lorsque vous utilisez des modules explicites. Lors du débogage de code construit localement, LLDB peut désormais importer des modules Swift et Clang explicitement construits directement à partir des artefacts de construction du projet. Cela évite d'avoir à recompiler les dépendances implicites des modules Clang à partir des sources, ce qui peut prendre beaucoup de temps, et est très sensible aux problèmes liés aux chemins de recherche des en-têtes. Si la première commande p ou po dans LLDB prend beaucoup de temps à cause de la compilation des modules Clang, ou si votre débogage est fréquemment bloqué par des problèmes d'importation d'en-têtes Clang, envisagez d'adopter des modules explicites dans votre projet;
Swift Testing
Swift 6 introduit "Swift Testing", une nouvelle bibliothèque de test conçue dès le départ pour Swift. Elle comprend des API expressives qui facilitent l'écriture et l'organisation des tests. Elle fournit des résultats détaillés lorsqu'un test échoue en utilisant des macros comme #expect. Enfin, elle s'adapte aux bases de code volumineuses grâce à des fonctionnalités telles que la paramétrisation, qui permet de répéter facilement un test avec des arguments différents.
Exemple :
Code : | Sélectionner tout |
1 2 3 4 5 6 | @Test("Continents mentioned in videos", arguments: [ "A Beach", "By the Lake", "Camping in the Woods" ]) func mentionedContinents(videoName: String) async throws { let videoLibrary = try await VideoLibrary() let video = try #require(await videoLibrary.video(named: videoName)) #expect(video.mentionedContinents.count <= 3) } |
Swift Testing étant inclus directement dans les chaînes d'outils de Swift 6, vous pouvez utiliser import Testing sans avoir besoin de déclarer une dépendance de paquetage. Cela signifie que vos tests n'ont pas besoin de construire Swift Testing ou ses dépendances (y compris swift-syntax), et que son implémentation macro est préconstruite. Le gestionnaire de paquets de Swift 6 construit et exécute automatiquement les tests de Swift Testing en plus de XCTests (s'il est présent), et affiche les résultats des deux bibliothèques dans le journal de sortie. Swift Testing est compatible avec toutes les plateformes officiellement prises en charge par Swift, y compris toutes les plateformes Apple, Linux et Windows.
Prise en charge de plateforme
Swift est conçu pour prendre en charge le développement et l'exécution sur tous les principaux systèmes d'exploitation, et la cohérence et l'expansion des plateformes sous-tendent la capacité de Swift à atteindre de nouveaux domaines de programmation. Swift 6 apporte des améliorations majeures à Linux et Windows, y compris la prise en charge d'un plus grand nombre de distributions Linux et d'architectures Windows.
Swift 6 prend en charge la création d'exécutables à liaison statique pour Linux ; ces exécutables n'ont pas de dépendances externes et sont donc idéaux pour les situations où vous souhaitez copier un programme directement sur un système ou dans un conteneur et l'exécuter sans installer de logiciel supplémentaire. Le SDK peut également être utilisé pour effectuer une compilation croisée vers Linux à partir d'autres plateformes. Swift 6 ajoute également une prise en charge officielle et des tests pour Debian et Fedora, ainsi que pour Ubuntu 24.04.
Des chaînes d'outils préconstruites sont désormais disponibles pour l'architecture arm64, ce qui améliore les performances du compilateur pour Windows sur les hôtes ARM. Dans Swift 6, le gestionnaire de paquets Swift parallélise également par défaut les compilations sur plusieurs cœurs sous Windows. Sur une machine à 10 cœurs, cela peut améliorer les performances de compilation d'un facteur 10.
Source : Annonce de Swift 6
Et vous ?
Que pensez-vous de cette nouvelle version de Swift ?
Voir aussi :
En route vers Swift 6 : l'équipe en charge du développement de Swift dévoile la nouvelle feuille de route du projet
Le navigateur Ladybird commencera à utiliser le langage Swift au lieu de C++ cet automne, car Swift offre une sécurité de la mémoire et est également un langage moderne avec une ergonomie solide
Apple recrute des développeurs de compilateurs pour améliorer l'interopérabilité entre Swift et C++