Introduzione a Swift Parte 1

Al WWDC 2014, Apple ha introdotto uno dei più grandi aggiornamenti per iOS dal 2008 dal punto di vista degli sviluppatori. Hanno introdotto HomeKit, HealthKit, CloudKit ed estensioni, solo per citarne alcuni. Ma la sorpresa più grande del WWDC 2014 è stata l'introduzione di un nuovo linguaggio di programmazione, Swift.

Swift è un meraviglioso linguaggio di programmazione che è stato costruito da zero per essere efficiente e sicuro. Usa le stesse API di Objective-C. Oppure, cosa puoi fare in Objective-C, puoi farlo in Swift. Introduce anche alcuni nuovi concetti che i programmatori di lunga data apprezzeranno e alcuni dei quali tratterò in questa serie introduttiva su Swift.

In questa serie, assumerò che tu abbia già familiarità con Objective-C. Nel primo articolo di questa serie, parlo della filosofia, della struttura dei file e della sintassi di Swift. Nel secondo articolo, eseguo lo zoom su aspetti più avanzati della sintassi di Swift, come gli optionals e la gestione della memoria. Aspetta i tuoi cappelli, gente, sarà un gran daffare.

1. Filosofia

Per capire meglio Swift, Apple ci ha condizionato con miglioramenti strutturali nell'Obiettivo-C negli ultimi anni. Miglioramenti Objective-C come blocchi di codice, array letterale e definizioni del dizionario e ARC (Automatic Reference Counting) sono solo alcune cose aggiunte da Apple all'Objective C che facilitano il passaggio a Swift.

Un importante pilastro della filosofia di Swift è l'inizializzazione del codice. Tutti gli oggetti e le variabili definiti in Swift devono essere inizializzati nel codice. Un oggetto o una variabile non inizializzati genererà un errore in fase di compilazione in Swift. Ciò garantisce che un oggetto o una variabile abbia sempre un valore. C'è un caso speciale in Swift per quando non è possibile definire un valore iniziale. In questo caso speciale, la tua variabile è chiamata a opzionale. Tratteremo gli optionals nella seconda parte di questa serie.

Un altro importante pilastro è la completezza delle filiali. Tutti i rami condizionali, si Se o scatola dell'interruttore, deve coprire tutte le condizioni. In questo modo, nessun codice può cadere senza che sia coperto. Manca una condizione nell'istruzione branch e verrà generato un errore di compilazione.

Un ultimo elemento della filosofia di Swift è la sua preferenza per le costanti rispetto alle variabili. Swift definisce variabili e costanti nel modo seguente:

let someConstant: String = "Questa è una costante" var someVariable: String = "Questa è una variabile"

Nell'esempio sopra, il permettere la parola chiave è usata per definire una costante mentre il var parola chiave definisce una variabile. Rendendo facile la definizione delle costanti, Apple incoraggia l'uso delle costanti quando possibile. Questo porta a un codice più sicuro in un ambiente multithread e una migliore ottimizzazione del codice in quanto il compilatore sa che il valore di una costante non cambierà.

Ora, c'è molto di più in Swift di alcuni miglioramenti della sintassi e della formattazione. Swift è stato costruito da zero per risolvere molti comuni C / C ++, e intrinsecamente Objective-C, fonti di crash. Problemi come:

  • indici out-of-bound negli array
  • dati non inizializzati
  • tipi di ritorno non controllati
  • accesso puntatore non controllato
  • implicita caduta 
  • errori di goto

Come qualcuno che programma sia per iOS che per Android, conosco di prima mano quanto sia più divertente la codifica per la piattaforma iOS con Cocoa e Uikit. Questa serie ti mostrerà quanto Più divertimento la codifica può essere aggiungendo Swift al mix.

2. Struttura del file

In Objective-C, abbiamo intestazione File (.h) e implementazione File (.m). Questo è qualcosa che Objective-C ha ereditato dal linguaggio C..

In Swift, una classe è definita in un singolo file di implementazione (.veloce) che include tutte le definizioni e le implementazioni della classe. Questo richiama ad altri linguaggi come Java e C #.

È finita la necessità di manipolare i file di intestazione e aggiungere il fastidioso #ifndef nella parte superiore dei file di intestazione.

3. Sintassi

La prima cosa che noterai di Swift è la scomparsa del punto e virgola alla fine di ogni affermazione. In Swift, ogni riga è considerata una dichiarazione e noi no dovere aggiungi un punto e virgola alla fine di ogni riga.

Sottolineo dovere, perché nulla ti impedisce di aggiungere punto e virgola alla fine delle tue dichiarazioni. Continuerò ad aggiungere punto e virgola alla fine di ogni affermazione poiché penso che aumenti la leggibilità. Inoltre, è davvero difficile sbarazzarsi dell'abitudine di aggiungere punti e virgola come gli sviluppatori di Cocoa hanno fatto per anni.

Un altro cambiamento importante in Swift è che le parentesi graffe sono obbligatorie per Se dichiarazioni. Ciò significa che non ci sono più bug Heartbleed.

La sintassi può essere un argomento complesso su cui scrivere. Swift ha un sacco di sottigliezze che possono richiedere molto tempo per andare oltre, ma questo non è l'obiettivo di questo articolo. Per brevità, mi concentrerò sulle modifiche che uno sviluppatore di Objective-C noterebbe.

4. Somiglianze con l'obiettivo-C

Inizierò mostrandoti tre frammenti di codice che illustrano alcune delle somiglianze con Objective-C. Ti aiuterà nella comprensione della lingua Swift.

// Objective-C per (int index = 0; index < 5; i++)  NSLog(@"%d",index);  // Swift for index in 1… <5  plrintln("\(index)"); 
// Switch Objective-C (index) case 0: break; caso 1: pausa; default: break;  // Swift switch (index) case 0: case 1: default: // nessuna istruzione break
// Objective-C if (index == 0)  // Swift if index == 0  // parentesi sono facoltativi // le parentesi graffe sono obbligatorie

I programmatori Objective-C scopriranno che Swift ha le stesse istruzioni di iterazione e di ramo con cui hai già familiarità, come ad esempio se altro,  per loop, per ... in cicli, e interruttore dichiarazioni.

Swift include due operatori di intervallo, ... < e ... , per specificare un intervallo di valori. In quanto sopra per loop, usiamo il operatore della gamma semichiuso, ... <, per specificare un intervallo di valori che include 1, 2, 3 e 4, ma esclude 5. L'altro operatore di intervallo è il operatore a raggio chiuso, ... . Specifica un intervallo di valori che include il valore su entrambi i lati dell'operatore dell'intervallo chiuso. Per esempio, 1 ... 5. specifica un intervallo di valori compreso tra 1 e 5, incluso 5.

5. Definizione di variabili e costanti

Rivediamo l'esempio che ti ho mostrato prima.

let someConstant: String = "Questa è una costante"; var someVariable: String = "Questa è una variabile";

In Swift, definiamo le costanti usando il permettere parola chiave e variabili usando il var parola chiave. Il colon, : ,è un marcatore per definire i tipi. Nell'esempio sopra, stiamo creando una costante e una variabile di tipo Stringa.

Stiamo anche inizializzando la costante e la variabile con una stringa. In Swift, le stringhe sono definite proprio come le stringhe C in Objective-C, non sono precedute da un @ simbolo.

Objective-C è un linguaggio fortemente tipizzato, il che significa che il tipo di una variabile o parametro deve sempre essere specificato. Swift è anche un linguaggio fortemente tipizzato, ma Swift è un po 'più intelligente in quanto il compilatore dedurrà il tipo di una variabile. Il compilatore si assicura anche che non avvenga un cast non corretto delle variabili senza la tua conoscenza e il tuo intervento.

Se riscriviamo l'esempio precedente lasciando che l'inferenza di tipo faccia il suo lavoro, lo snippet di codice appare come segue:

let someConstant = "Questa è una costante"; var someVariable = "Questa è una variabile"; lascia un po 'diInt = 1; let someFloat = 1.0;

Questo è molto meglio e il codice è molto più pulito. Il compilatore è abbastanza intelligente da capirlo someInt è un Int e someFloat è un Doppio.

6. Archi

Un modo per avere un'idea della forza di una lingua è esplorare come gestisce la manipolazione delle stringhe. Objective-C ha un sacco di funzioni e caratteristiche che ci permettono di gestire le stringhe, meglio della maggior parte delle lingue, ma tendono ad essere prolissi e confusionari di volta in volta.

Iniziamo con un esempio Objective-C. Per concatenare due stringhe in Objective-C, facciamo quanto segue:

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

In Swift, per aggiungere una stringa ad un'altra stringa, usiamo il + operatore. È così semplice.

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

Le stringhe in Swift sono Unicode, il che significa che possiamo scrivere:

let string = "你好 世界"

Possiamo iterare i caratteri di una stringa usando a per ... in dichiarazione come mostrato nell'esempio seguente. Possiamo usare a per ... in loop per iterare anche le stringhe Unicode. È davvero fantastico.

let str = "Ciao"; per char in str println (char);  // output // H // e // l // l // o

Un'ultima cosa che mi piacerebbe fare riguardo alle stringhe prima di procedere è l'interpolazione delle stringhe. In Objective-C, se vogliamo generare una stringa con variabili, invochiamo [NSString stringWithFormat:]. In Swift, le variabili possono essere incorporate. Dai un'occhiata al seguente esempio.

sia x = 4; sia y = 5; println ("\ (x) x \ (y) = \ (x * y)") // output // 4 x 5 = 20

Per usare l'interpolazione di stringhe, racchiudi tra parentesi la variabile o la chiamata di funzione e mettici una barra rovesciata di fronte ad essa, \ (espressione).

7. Array e dizionari

schieramento & Dizionario

Come programmatore Objective-C, hai già familiarità con array e dizionari. Swift ha anche classi di raccolta e aggiunge alcune funzionalità aggiuntive a loro.

Come usi le raccolte in Swift? In Swift, vengono chiamati schieramento e Dizionario. Dichiarare un array in Swift è come dichiarare un array letterale in Objective-C, usando un insieme di parentesi quadre, [], ma senza un @ simbolo che li precede.

let someArray: [String] = ["one", "two", "three"]; var someOtherArray: [String] = ["alpha", "beta", "gamma"];

Lo stesso vale per i dizionari. Tuttavia, invece di usare parentesi graffe, si usano parentesi quadre.

let someDictionary: [String: Int] = ["one": 1, "two": 2, "three": 3]; var someOtherDictionary: [String: Int] = ["cats": 1, "dogs": 4, "mouse": 3];

Mutabilità

Se uno schieramento oggetto è equivalente a un NSArray oggetto e a Dizionario oggetto è equivalente a un NSDictionary oggetto, quindi come possiamo creare matrici e dizionari mutabili in Swift?

La risposta è molto semplice, dichiarare l'oggetto come una variabile. In altre parole, nell'esempio precedente someArray è l'equivalente di un NSArray istanza e someOtherArray quello di un NSMutableArray esempio. Questo vale anche per i dizionari. Nell'esempio precedente, someDictionary è l'equivalente di un NSDictionary istanza e someOtherDictionary quello di un NSMutableDictionary esempio. È pulito, giusto?

Mentre gli array ei dizionari Objective-C possono contenere solo oggetti, in Swift le raccolte possono contenere oggetti e anche tipi di dati primitivi, come numeri interi e float. Un'altra importante differenza con Objective-C è che le raccolte in Swift vengono digitate, esplicitamente o tramite l'inferenza del tipo in fase di compilazione. Specificando il tipo di oggetti in una raccolta, Swift aggiunge ulteriore sicurezza a queste raccolte.

Anche se possiamo omettere il tipo di una variabile quando lo dichiariamo, non altera il fatto che il compilatore assegna i tipi agli oggetti di una collezione. L'uso dell'inferenza di tipo aiuta a mantenere leggibile e leggibile il codice.

Possiamo ridichiarare il schieramento e Dizionario oggetti che abbiamo dichiarato in precedenza come segue:

let someArray = ["one", "two", "three"]; var someOtherArray = ["alpha", "beta", "gamma"]; let someDictionary = ["one": 1, "two": 2, "three": 3]; var someOtherDictionary = ["cats": 1, "dogs": 4, "topi": 3];

Il compilatore controllerà le collezioni durante la loro inizializzazione e dedurrà il tipo corretto. In altre parole, lo capisce someArray e someOtherArray sono una collezione di Stringa oggetti e someDictionary e someOtherDictionary sono dizionari con chiavi di tipo Stringa e valori di tipo Int.

Manipolazione delle collezioni

L'aggiunta di un oggetto o di un altro array a un array è molto simile alla concatenazione di stringhe in quanto viene utilizzato anche il + operatore.

var array = ["one", "two", "three"]; // mutable array array + = "four"; // aggiungi elemento a array array + = ["five", "six"]; // aggiungi una matrice all'array

Manipolare i dizionari è altrettanto facile.

var dictionary = ["cat": 2, "dog": 4, "snake": 8]; // dizionario dizionario mutevole ["lion"] = 7; // aggiungi elemento al dizionario dizionario + = ["bear": 1, "mouse": 6]; // aggiungi un dizionario al dizionario

Collezioni tipizzate

In precedenza ho menzionato che le raccolte in Swift sono state digitate, ma cosa significa? Se definiamo una collezione che contiene Stringa oggetti, puoi solo aggiungere Stringa oggetti a quella raccolta. In caso contrario si verificherà un errore.

Diamo un'occhiata a un esempio per chiarire questo. Definiamo una collezione di Auto oggetti. Il seguente frammento di codice mostra il Auto definizione della classe e matrice mutabile macchine, contenente tre Auto casi.

// Car class class Car var speed = 0.0 func accelerate (per: Double = 1.0) -> Bool speed + = by; ritorna vero;  var cars = [Car (), Car (), Car ()]; 

Dietro le quinte, il compilatore dedurrà il tipo dell'array. Se vogliamo aggiungere un nuovo Auto istanza alla raccolta, possiamo semplicemente usare il + operatore come mostrato di seguito.

auto + = Car ();

Tuttavia, l'aggiunta di un oggetto di un tipo diverso provocherà un errore.

cars + = "Some String"; // questo causerà un errore del compilatore

Questo ha il vantaggio aggiunto di sicurezza del tipo per il recupero di oggetti dalle raccolte. Elimina anche la necessità di lanciare oggetti di raccolta prima di utilizzarli.

Nel nostro esempio, a Auto l'oggetto ha un accelerare metodo. Poiché una raccolta viene digitata, possiamo afferrare un elemento dall'array e invocare immediatamente un metodo sull'oggetto, in una riga di codice. Non dobbiamo preoccuparci del tipo di elemento poiché contiene solo la raccolta Auto oggetti.

auto [0]. accelerare (per: 2.0);

Per realizzare la stessa cosa in Objective-C con lo stesso livello di sicurezza, dovremmo scrivere quanto segue:

puntatore id = auto [0]; if ([pointer isKindOfClass: [Car class]]) Car * car = (Car *) puntatore; [auto accelerateBy: 2.0]; 

Infine, per iterare un array, usiamo a per ... in ciclo continuo:

per auto in auto car.accelerate (per: 2.0); 

Per iterare un dizionario, usiamo anche a per ... in ciclo continuo:

for (chiave, valore) in someDictionary println ("Chiave \ (chiave) ha valore \ (valore)"

Come puoi vedere, le raccolte tipizzate sono una potente funzionalità del linguaggio Swift.

Conclusione

 Abbiamo già imparato molto sul linguaggio Swift e dovresti prenderti il ​​tempo per farlo sprofondare. Ti consiglio di scaricare Xcode 6 il prima possibile e di iniziare ad applicare ciò che hai imparato in questo articolo nel nuovo Xcode Terreno di gioco caratteristica. Playground ti consente di giocare con Swift in tempo reale.

Questo è tutto per questo articolo. Nella prossima puntata di questa serie, daremo un'occhiata a tuple, funzioni, chiusure, classi e, ultimo ma non meno importante, optionals. Imparerai anche come funziona la gestione della memoria in Swift. Rimanete sintonizzati.