Une introduction à Swift Partie 1

À la WWDC 2014, Apple a présenté l'une des mises à jour les plus importantes d'iOS depuis 2008 du point de vue du développeur. Ils ont introduit HomeKit, HealthKit, CloudKit et Extensions, pour n'en nommer que quelques-uns. La plus grande surprise de la WWDC 2014 a été l’introduction d’un tout nouveau langage de programmation, Swift..

Swift est un merveilleux langage de programmation qui a été conçu dès le départ pour être efficace et sûr. Il utilise les mêmes API que Objective-C. Ou, ce que vous pouvez faire dans Objective-C, vous pouvez le faire dans Swift. Il introduit également quelques nouveaux concepts que les programmeurs de longue date apprécieront et dont je traiterai certains dans cette série d'introduction sur Swift..

Dans cette série, je suppose que vous connaissez déjà Objective-C. Dans le premier article de cette série, je parle de la philosophie, de la structure de fichier et de la syntaxe de Swift. Dans le deuxième article, je fais un zoom sur des aspects plus avancés de la syntaxe de Swift, tels que les options et la gestion de la mémoire. Accrochez-vous à votre chapeau, les gens, ça va être un doozy.

1. la philosophie

Pour mieux comprendre Swift, Apple nous a conditionnés à apporter des améliorations structurelles à Objective-C au cours des dernières années. Les améliorations d'Objective-C telles que les blocs de code, les définitions de dictionnaire et de tableaux littéraux, ainsi que le calcul automatique des références (ARC) ne sont que quelques-unes des choses ajoutées par Apple à Objective-C qui facilitent la transition vers Swift..

L’initialisation du code est l’un des piliers de la philosophie de Swift. Tous les objets et variables définis dans Swift doivent être initialisés en code. Un objet ou une variable non initialisé entraînera une erreur de temps de compilation dans Swift. Cela garantit qu'un objet ou une variable a toujours une valeur. Swift présente un cas particulier pour lequel une valeur initiale ne peut pas être définie. Dans ce cas particulier, votre variable s'appelle un optionnel. Nous couvrirons les optionnels dans la deuxième partie de cette série.

La complétude des succursales est un autre pilier important. Toutes les branches conditionnelles, que ce soit si ou commutateur / boîtier, doit couvrir toutes les conditions. De cette façon, aucun code ne peut tomber sans qu'il soit couvert. L'absence d'une condition dans votre déclaration de branche sera interceptée et générera une erreur de compilation.

Un dernier élément de la philosophie de Swift est sa préférence pour les constantes par rapport aux variables. Swift définit les variables et les constantes de la manière suivante:

let someConstant: String = "Ceci est une constante" var someVariable: String = "Ceci est une variable"

Dans l'exemple ci-dessus, le laisser mot-clé est utilisé pour définir une constante tandis que la var mot-clé définit une variable. En facilitant la définition des constantes, Apple encourage, dans la mesure du possible, l’utilisation de constantes. Cela conduit à un code plus sûr dans un environnement multithread et à une meilleure optimisation du code car le compilateur sait que la valeur d'une constante ne changera pas.

Maintenant, Swift ne se limite pas à quelques améliorations de la syntaxe et de la mise en forme. Swift a été conçu à partir de zéro pour résoudre de nombreuses sources de crash dans C / C ++, et par nature Objective-C. Des questions comme:

  • index hors limites dans les tableaux
  • données non initialisées
  • types de retour non contrôlés
  • accès non contrôlé au pointeur
  • chute implicite 
  • goto erreurs

En tant que programmeur pour iOS et Android, je sais à quel point coder avec plaisir sur la plate-forme iOS est vraiment plus amusant avec Cocoa et UIKit. Cette série va vous montrer combien plus amusant le codage peut être en ajoutant Swift au mélange.

2. Structure du fichier

En Objective-C, nous avons entête des dossiers (.h) et la mise en oeuvre des dossiers (.m). C'est quelque chose qu'Objective-C a hérité du langage C.

Dans Swift, une classe est définie dans un seul fichier d’implémentation (.rapide) qui inclut toutes les définitions et les implémentations de la classe. Cela rappelle d'autres langages comme Java et C #.

Fini la nécessité de jongler avec les fichiers d'en-tête et d'ajouter le satané #IFNDEF en haut des fichiers d'en-tête.

3. Syntaxe

La première chose que vous remarquerez à propos de Swift est la disparition du point-virgule à la fin de chaque déclaration. Dans Swift, chaque ligne est considérée comme une déclaration et nous ne le faisons pas. devoir ajouter un point-virgule à la fin de chaque ligne.

Je souligne devoir, parce que rien ne vous empêche d'ajouter des points-virgules à la fin de vos déclarations. Je continuerai d'ajouter des points-virgules à la fin de chaque déclaration, car je pense que cela améliore la lisibilité. En outre, il est très difficile de se débarrasser de l’habitude d’ajouter des points-virgules comme le font les développeurs de Cocoa depuis des années..

Un autre changement important à Swift est que les accolades sont obligatoires pour si déclarations. Cela signifie plus de bugs Heartbleed.

La syntaxe peut être un sujet complexe sur lequel écrire. Swift a beaucoup de subtilités qui peuvent prendre beaucoup de temps, mais ce n'est pas le but de cet article. Par souci de concision, je vais me concentrer sur les changements qu'un développeur Objective-C remarquerait.

4. Similitudes avec Objective-C

Je commencerai par vous montrer trois extraits de code illustrant certaines des similitudes avec Objective-C. Cela vous aidera dans votre compréhension de la langue Swift.

// Objective-C pour (int index = 0; index < 5; i++)  NSLog(@"%d",index);  // Swift for index in 1… <5  plrintln("\(index)"); 
// commutateur Objective-C (index) case 0: break; cas 1: pause; défaut: break;  // commutateur rapide (index) cas 0: cas 1: défaut: // pas d'instruction break
// Objective-C if (index == 0)  // Swift si index == 0  // les parenthèses sont facultatives // les accolades sont obligatoires

Les programmeurs Objective-C constateront que Swift a les mêmes instructions de branche et d’itération que vous connaissez déjà, telles que sinon,  pour boucles, pour… dans boucles, et commutateur des déclarations.

Swift comprend deux opérateurs de gamme, … < et , pour spécifier une plage de valeurs. Au dessus pour boucle, on utilise le opérateur de champ semi-fermé, … <, pour spécifier une plage de valeurs comprenant 1, 2, 3 et 4, mais en exclure 5. L’autre opérateur de plage est le opérateur fermé, . Il spécifie une plage de valeurs qui inclut la valeur des deux côtés de l'opérateur de plage fermée. Par exemple, 1… 5. spécifie une plage de valeurs de 1 à 5, y compris 5.

5. Définition des variables et des constantes

Reprenons l'exemple que je vous ai montré plus tôt.

let someConstant: String = "Ceci est une constante"; var someVariable: String = "Ceci est une variable";

Dans Swift, nous définissons les constantes en utilisant le laisser mot clé et variables utilisant le var mot-clé. Le colon, : ,est un marqueur pour définir les types. Dans l'exemple ci-dessus, nous créons une constante et une variable de type Chaîne.

Nous initialisons également la constante et la variable avec une chaîne. Dans Swift, les chaînes sont définies comme les chaînes C dans Objective-C, elles ne sont pas précédées par un @ symbole.

Objective-C est un langage fortement typé, ce qui signifie que le type d'une variable ou d'un paramètre doit toujours être spécifié. Swift est aussi un langage fortement typé, mais Swift est un peu plus intelligent, car le compilateur déduira le type d'une variable. Le compilateur s'assure également qu'aucune conversion incorrecte de variables ne se produit sans votre connaissance et votre intervention exprimées..

Si nous réécrivons l'exemple ci-dessus en laissant l'inférence de type fonctionner, l'extrait de code se présente comme suit:

let someConstant = "Ceci est une constante"; var someVariable = "Ceci est une variable"; laissez someInt = 1; Soit someFloat = 1,0;

C'est beaucoup mieux et le code est beaucoup plus propre. Le compilateur est assez intelligent pour comprendre que un peu est un Int et un peu flottant est un Double.

6. Cordes

Une façon de se faire une idée de la force d’une langue consiste à explorer la manière dont elle gère la manipulation des cordes. Objective-C possède de nombreuses fonctions et fonctionnalités qui nous permettent de gérer les chaînes, mieux que la plupart des langages, mais elles ont tendance à être verbeuses et confuses de temps en temps..

Commençons par un exemple Objective-C. Pour concaténer deux chaînes dans Objective-C, procédez comme suit:

NSString * string = @ "Hello"; NSString * greeting = [string stringByAppendingString: @ "World!"];

Dans Swift, pour ajouter une chaîne à une autre chaîne, nous utilisons le + opérateur. C'est si simple.

let string = "Hello" let greeting = string + "World!"

Les chaînes dans Swift sont Unicode, ce qui signifie que nous pouvons écrire:

let string = ""

On peut itérer les caractères d'une chaîne en utilisant un pour… dans comme le montre l'exemple suivant. Nous pouvons utiliser un pour… dans boucle pour itérer des chaînes Unicode aussi. C'est vraiment cool.

let str = "Bonjour"; pour char in str println (char);  // sorties // H // e // l // l // o

Une dernière chose que je voudrais aborder à propos des chaînes avant de poursuivre est l’interpolation des chaînes. En Objective-C, si nous voulons sortir une chaîne avec des variables, nous appelons [NSString stringWithFormat:]. Dans Swift, les variables peuvent être intégrées. Regardez l'exemple suivant.

Soit x = 4; Soit y = 5; println ("\ (x) x \ (y) = \ (x * y)") // génère // 4 x 5 = 20

Pour utiliser l'interpolation de chaîne, vous placez la variable ou l'appel de fonction entre parenthèses et vous placez une barre oblique inverse devant celle-ci., \( expression).

7. Tableaux et dictionnaires

Tableau Et dictionnaire

En tant que programmeur Objective-C, vous connaissez déjà les tableaux et les dictionnaires. Swift a également des classes de collection et leur ajoute quelques fonctionnalités supplémentaires.

Comment utilisez-vous les collections dans Swift? En Swift, ils s'appellent Tableau et dictionnaire. Déclarer un tableau dans Swift est similaire à déclarer un littéral de tableau dans Objective-C, en utilisant un jeu de crochets, [], mais sans un @ symbole qui les précède.

let someArray: [String] = ["un", "deux", "trois"]; var someOtherArray: [String] = ["alpha", "beta", "gamma"];

La même chose vaut pour les dictionnaires. Cependant, au lieu d’utiliser des accolades, vous utilisez des crochets.

let someDictionary: [String: Int] = ["un": 1, "deux": 2, "trois": 3]; var someOtherDictionary: [String: Int] = ["chats": 1, "chiens": 4, "souris": 3];

Mutabilité

Si un Tableau objet est équivalent à un NSArray objet et un dictionnaire objet est équivalent à un NSDictionary objet, alors comment créons-nous des tableaux et des dictionnaires mutables dans Swift?

La réponse est très simple, déclarez l'objet en tant que variable. En d'autres termes, dans l'exemple précédent un peu est l'équivalent d'un NSArray exemple et un autre tableau celui d'un NSMutableArray exemple. Cela s’applique aussi aux dictionnaires. Dans l'exemple précédent, un peu de dictionnaire est l'équivalent d'un NSDictionary exemple et un autreDictionnaire celui d'un NSMutableDictionary exemple. C'est chouette, non?

Alors que les tableaux et les dictionnaires Objective-C ne peuvent contenir que des objets, dans Swift, les collections peuvent contenir des objets ainsi que des types de données primitifs, tels que des entiers et des flottants. Une autre différence importante avec Objective-C est que les collections dans Swift sont typées, explicitement ou par inférence de type lors de la compilation. En spécifiant le type des objets dans une collection, Swift ajoute une sécurité supplémentaire à ces collections..

Même si nous pouvons omettre le type d'une variable lors de sa déclaration, cela ne change rien au fait que le compilateur affectera des types aux objets d'une collection. L'utilisation de l'inférence de type aide à garder le code lisible et léger.

Nous pouvons redéclarer le Tableau et dictionnaire objets que nous avons déclarés précédemment comme suit:

let someArray = ["un", "deux", "trois"]; var someOtherArray = ["alpha", "beta", "gamma"]; let someDictionary = ["un": 1, "deux": 2, "trois": 3]; var someOtherDictionary = ["chats": 1, "chiens": 4, "souris": 3];

Le compilateur inspectera les collections lors de leur initialisation et en déduira le type correct. En d'autres termes, il comprend que un peu et un autre tableau sont une collection de Chaîne objets et un peu de dictionnaire et un autreDictionnaire sont des dictionnaires avec des clés de type Chaîne et valeurs de type Int.

Manipulation de la collection

Ajouter un objet ou un autre tableau à un tableau est très similaire à la concaténation de chaînes en ce que nous utilisons également le + opérateur.

var array = ["un", "deux", "trois"]; // tableau mutable tableau + = "quatre"; // ajoute un élément au tableau array + = ["five", "six"]; // ajoute un tableau à un tableau

Manipuler des dictionnaires est tout aussi facile.

var dictionnaire = ["chat": 2, "chien": 4, "serpent": 8]; // dictionnaire mutable dictionary ["lion"] = 7; // ajouter un élément au dictionnaire dictionary + = ["bear": 1, "mouse": 6]; // ajouter un dictionnaire au dictionnaire

Collections dactylographiées

J'ai mentionné précédemment que les collections dans Swift sont dactylographiées, mais qu'est-ce que cela signifie? Si nous définissons une collection qui contient Chaîne objets, vous ne pouvez ajouter que Chaîne objets à cette collection. Ne pas le faire entraînera une erreur.

Regardons un exemple pour clarifier cela. Nous définissons une collection de Voiture objets. L'extrait de code suivant montre le Voiture définition de classe et un tableau mutable des voitures, contenant trois Voiture les instances.

// Classe de voiture Car var vitesse = 0.0 fonction accélérer (par: Double = 1.0) -> Bool vitesse + = par; retourne vrai;  var cars = [Car (), Car (), Car ()]; 

Dans les coulisses, le compilateur déduira le type du tableau. Si nous voulons ajouter un nouveau Voiture par exemple à la collection, nous pouvons simplement utiliser le + opérateur comme indiqué ci-dessous.

voitures + = voiture ();

Cependant, l'ajout d'un objet d'un type différent entraînera une erreur.

cars + = "Some String"; // cela provoquera une erreur du compilateur

Cela présente l'avantage supplémentaire de la sécurité de type pour la récupération d'objets à partir de collections. Cela élimine également le besoin de lancer des objets de collection avant de les utiliser.

Dans notre exemple, un Voiture l'objet a un accélérer méthode. Puisqu'une collection est typée, nous pouvons récupérer un élément du tableau et invoquer immédiatement une méthode sur l'objet, sur une ligne de code. Nous n'avons pas à nous soucier du type de l'élément car la collection ne contient que Voiture objets.

voitures [0] .accelerate (by: 2.0);

Pour accomplir la même chose dans Objective-C avec le même niveau de sécurité, il faudrait écrire ce qui suit:

pointeur id = voitures [0]; if ([pointeur isKindOfClass: [classe de voiture]]) voiture * voiture = (voiture *) pointeur; [accélération de la voiturePar: 2.0]; 

Enfin, pour itérer un tableau, nous utilisons un pour… dans boucle:

pour voiture en voiture voiture.accélérer (par: 2.0); 

Pour itérer un dictionnaire, nous utilisons également un pour… dans boucle:

for (clé, valeur) dans someDictionary println ("Key \ (key) a la valeur \ (value)"

Comme vous pouvez le constater, les collections typées sont une fonctionnalité puissante du langage Swift..

Conclusion

 Nous avons déjà beaucoup appris sur le langage Swift et vous devriez prendre le temps de le laisser pénétrer. Je vous recommande de télécharger Xcode 6 dès que possible et de commencer à appliquer ce que vous avez appris dans cet article dans la nouvelle version de Xcode. Cour de récréation fonctionnalité. Les terrains de jeu vous permettent de jouer avec Swift en temps réel.

C'est tout pour cet article. Dans le prochain épisode de cette série, nous examinons les n-uplets, les fonctions, les fermetures, les classes et enfin les options. Vous apprendrez également comment fonctionne la gestion de la mémoire dans Swift. Restez à l'écoute.