Swift From Scratch Optionals e Control Flow

Negli articoli precedenti hai appreso alcuni concetti base del linguaggio di programmazione Swift. Se hai programmato prima, sono sicuro che hai visto alcune somiglianze con altri linguaggi di programmazione, come Ruby, JavaScript e Objective-C.

In questo articolo, ingrandiamo il flusso di controllo in Swift. Prima di poter discutere del flusso di controllo in modo più dettagliato, dobbiamo dare un'occhiata a un concetto che è nuovo alla maggior parte di voi, optionals. Gli optional sono un'altra caratteristica di sicurezza di Swift. All'inizio, potrebbe sembrare una seccatura usare gli optionals, ma imparerai rapidamente che gli optionals renderanno il tuo codice molto più sicuro.

1. Opzionali

Abbiamo già visto che una variabile deve essere inizializzata prima di poter essere utilizzata. Dai un'occhiata al seguente esempio per capire meglio cosa significa.

var str: String str.isEmpty

Se sei abituato a lavorare con le stringhe in Objective-C, potresti essere sorpreso che Swift ti mostri un errore. Vediamo cosa ci dice quell'errore.

In molte lingue, le variabili hanno un valore di default iniziale. In Objective-C, ad esempio, la stringa nel seguente frammento di codice è uguale a zero.

NSString * newString;

Tuttavia, il concetto di zero differisce in Swift e Objective-C. Discuteremo zero più in dettaglio un po 'più tardi.

Cos'è un optional?

Swift usa gli optionals per incapsulare un concetto importante, cioè una variabile o costante ha un valore o non lo ha. È così semplice in Swift. Per dichiarare una variabile o una costante come facoltativa, aggiungiamo un punto interrogativo al tipo di variabile o costante.

var str: String?

La variabile str non è più di tipo Stringa. È ora di tipo opzionale Stringa. Questo è importante da capire. Il risultato o l'effetto collaterale è che non possiamo più interagire direttamente con il valore di str variabile. Il valore è memorizzato in modo sicuro nell'opzionale, e dobbiamo chiedere all'opzionale il valore che incapsula.

Forzato Unwrapping

Un modo per accedere al valore di un opzionale è attraverso lo scostamento forzato. Possiamo accedere al valore della variabile str aggiungendo un ! al nome della variabile.

var str: String? str = "Test" print (str!)

È importante assicurarsi che l'opzione contenga un valore quando si forza a scartarlo. Se l'opzionale non ha un valore e lo forzate a scartarlo, Swift genererà un errore.

Associazione facoltativa

C'è un modo più sicuro per accedere al valore di un opzionale. Daremo un'occhiata più da vicino Se dichiarazioni in pochi minuti, ma il seguente esempio mostra come possiamo accedere in sicurezza al valore memorizzato nella variabile str, che è di tipo opzionale Stringa.

var str: String? if str! = nil print (str!) else print ("str non ha valore")

Per prima cosa controlliamo se la variabile str è uguale a zero prima di stampare il suo contenuto. In questo esempio, str non ha un valore, il che significa che non verrà forzatamente scartato per errore.

C'è un approccio più elegante chiamato associazione opzionale. Nell'esempio seguente, assegniamo il valore memorizzato in facoltativo a una costante temporanea, che viene utilizzata nel file Se dichiarazione. Il valore dell'opzionale str è legato alla costante strConst e usato nel Se dichiarazione. Questo approccio funziona anche per mentre dichiarazioni.

var str: String? str = "Test" se lasci strConst = str print (strConst) else print ("str non ha valore")

Cosa è zero?

Se vieni da Objective-C, sicuramente saprai cosa zero è. In Objective-C, zero è un puntatore a un oggetto che non esiste. Swift definisce zero un po 'diverso, ed è importante che tu capisca la differenza.

In Swift, zero significa l'assenza di un valore, qualsiasi valore. Mentre zero è applicabile solo agli oggetti in Objective-C, in Swift zero può essere usato per qualsiasi tipo È quindi importante capire che un optional non è l'equivalente di zero in Objective-C. Questi concetti sono molto diversi.

2. Flusso di controllo

Swift offre una serie di costrutti comuni per controllare il flusso del codice che scrivi. Se hai qualche esperienza di programmazione, allora non avrai problemi a familiarizzare con i costrutti del flusso di controllo di Swift, condizionale Se e interruttore dichiarazioni, e per e mentre loop.

Tuttavia, Swift non sarebbe Swift se il suo flusso di controllo non differisse leggermente, ad esempio, dai costrutti del flusso di controllo di Objective-C. Anche se i dettagli sono importanti, sono sicuro che non ti impediranno di essere al passo con Swift. Iniziamo con il costrutto condizionale più comune, il Se dichiarazione.

Se

Swift Se le dichiarazioni sono molto simili a quelle che si trovano nell'Obiettivo-C. La differenza principale è che non è necessario avvolgere la condizione tra parentesi. Le parentesi graffe, tuttavia, sono obbligatorie. Quest'ultimo impedisce agli sviluppatori di introdurre bug comuni relativi alla scrittura Se affermazioni senza parentesi graffe. Questo è ciò che Se l'affermazione è come in Swift.

sia a = 10 se a> 10 print ("Il valore di \" a \ "è maggiore di 10.") else print ("Il valore di \" a \ "è minore o uguale a 10." )

Non dovrebbe sorprendere che Swift definisca anche un altro clausola. Il codice nel altro la clausola viene eseguita se la condizione è uguale a falso. È anche possibile catena Se dichiarazioni come mostrato nel prossimo esempio.

sia a = 10 se a> 10 print ("Il valore di \" a \ "è maggiore di 10.") else if a> 5 print ("Il valore di \" a \ "è maggiore di 5. ") else print (" Il valore di \ "a \" è minore o uguale a 5. ")

C'è una nota importante da fare, cioè la condizione di un Se la dichiarazione deve tornare vero o falso. Questo non è vero per Se dichiarazioni in Objective-C. Dai un'occhiata a quanto segue Se dichiarazione in Objective-C.

NSArray * array = @ []; if (array.count) NSLog (@ "La matrice contiene uno o più elementi.");  else NSLog (@ "L'array è vuoto."); 

Se dovessimo trasferire lo snippet di codice sopra a Swift, verificheremo un errore. L'errore non è molto informativo, ma Swift ci dice che dobbiamo garantire che il risultato della condizione venga valutato vero o falso.

Il modo corretto per tradurre lo snippet Objective-C sopra in Swift è assicurarsi che la condizione di Se la dichiarazione valuta a vero o falso, come nel seguente frammento.

let array = [String] () se array.count> 0 print ("La matrice contiene uno o più elementi.") else print ("La matrice è vuota.")

interruttore

Swift interruttore la dichiarazione è più potente del suo equivalente Objective-C. È anche più sicuro, come imparerai in un attimo. Mentre ci sono alcune differenze, interruttore le dichiarazioni in Swift aderiscono allo stesso concetto di quelle degli altri linguaggi di programmazione; un valore è passato al interruttore dichiarazione, e viene confrontato con possibili modelli di corrispondenza.

Esatto, schemi. Come ho detto, a interruttore l'affermazione in Swift ha qualche asso nella manica. Daremo un'occhiata a questi trucchi in un attimo. Parliamo prima di sicurezza.

Esauriente

UN interruttore l'affermazione in Swift deve essere esaustiva, vale a dire che ogni possibile valore del tipo che viene consegnato al interruttore la dichiarazione deve essere gestita dal interruttore dichiarazione. Come in Objective-C, questo è facilmente risolto aggiungendo a predefinito caso, come mostrato nell'esempio seguente.

lasciare a = 10 passare a caso 0: stampa ("a è uguale a 0") caso 1: stampa ("a è uguale a 1") predefinito: stampa ("a ha un altro valore")

Sfumare

Una differenza importante con l'implementazione di Objective-C di interruttore le affermazioni sono la mancanza di ricadute implicite. L'esempio seguente non funziona in Swift per alcuni motivi.

lasciare a = 10 passare a case 0: case 1: print ("a è uguale a 1") default: print ("a ha un altro valore")

Il primo caso in cui un è confrontato con 0 non cade implicitamente nel secondo caso in cui un è confrontato con 1. Se aggiungi l'esempio sopra al tuo parco giochi, noterai che Swift genera un errore. L'errore dice che ogni caso deve includere almeno un'istruzione eseguibile.

Si noti che i casi del interruttore la dichiarazione non include rompere dichiarazioni di uscire dal interruttore dichiarazione. Questo non è richiesto in Swift poiché la caduta implicita non esiste in Swift. Ciò eliminerà una serie di errori comuni causati da ricadute non intenzionali.

Patterns

Il potere di a interruttore l'affermazione in Swift sta nel pattern matching. Dai un'occhiata al seguente esempio in cui ho usato gli intervalli per confrontare il valore preso in considerazione.

lasciare a = 10 cambiare caso 0 ... <5: print("The value of a lies between 0 and 4.") case 5… 10: print("The value of a lies between 5 and 10.") default: print("The value of a is greater than 10.") 

Il ... < L'operatore o l'operatore di intervallo semiaperto definisce un intervallo dal primo valore al secondo valore, escludendo il secondo valore. Il ... L'operatore o l'operatore di intervallo chiuso definisce un intervallo dal primo valore al secondo valore, incluso il secondo valore. Questi operatori sono molto utili in una vasta gamma di situazioni.

È anche possibile confrontare il valore considerato di a interruttore dichiarazione a tuple. Dai un'occhiata al seguente esempio per vedere come funziona.

let latlng = (34.15, -78.03) cambia latlng case (0, 0): print ("Siamo al centro del pianeta.") case (0 ... 90, _): print ("Siamo dentro l'emisfero settentrionale. ") caso (-90 ... 0, _): print (" Siamo nell'emisfero australe. ") default: print (" La coordinata non è valida. ")

Come puoi vedere nell'esempio sopra, è possibile che il valore corrisponda a più di un caso. Quando ciò accade, viene scelto il primo caso corrispondente. L'esempio sopra illustra anche l'uso del trattino basso. Come abbiamo visto nel precedente articolo, possiamo usare un trattino basso, _, per dire a Swift quali valori non ci interessano.

Valore vincolante

Il valore vincolante è anche possibile con interruttore dichiarazioni, come dimostra il seguente esempio. Il secondo valore della tupla è temporaneamente associato alla costante descrizione per l'uso nel primo e nel secondo caso.

var response = (200, "OK") cambia risposta case (200 ... <400, let description): print("The request was successful with description \(description).") case (400… <500, let description): print("The request was unsuccessful with description \(description).") default: print("The request was unsuccessful with no description.") 

per

Il per loop è il primo costrutto di loop che daremo un'occhiata. Si comporta in modo molto simile a per loop in altre lingue. C'erano due sapori, il per loop e il per-in ciclo continuo. A partire da Swift 3, tuttavia, in stile C. per i loop non sono più disponibili. Lo snippet seguente non è possibile in Swift 3.

per var i = 0; io < 10; i++  print("i is equal to \(i).") 

Se incolli questo snippet in un parco giochi, noterai anche che il ++-- gli operatori non sono più disponibili in Swift 3.

Il per-in loop è l'ideale per il looping sui contenuti di una gamma o collezione. Nell'esempio seguente, eseguiamo il looping sugli elementi di un array.

let numbers = [1, 2, 3, 5, 8] per il numero in numeri print ("numero è uguale a \ (numero)")

Possiamo anche usare per-in loop per scorrere le coppie chiave-valore di un dizionario. Nell'esempio seguente, dichiariamo un dizionario e stampiamo i suoi contenuti sulla console. Come abbiamo visto in precedenza in questa serie, la sequenza delle coppie chiave-valore non è definita poiché un dizionario è un insieme non ordinato di coppie chiave-valore.

var bids = ["Tom": 100, "Bart": 150, "Susan": 120] per (nome, offerta) nelle offerte stampa ("L'offerta di \ (nome) è $ \ (offerta).") 

Ogni coppia chiave-valore del dizionario è disponibile nel per-in loop come una tupla di costanti nominate. Il per-in il ciclo è ottimo anche in combinazione con le gamme. Sono sicuro che sei d'accordo sul fatto che il frammento di seguito sia facile da leggere e capire grazie all'uso di un intervallo chiuso.

per i in 1 ... 10 print ("i è uguale a \ (i)")

mentre

Il mentre il ciclo arriva in due gusti, mentre e repeat-mentre. La differenza principale è che l'insieme delle dichiarazioni di a repeat-mentre il ciclo viene sempre eseguito almeno una volta, perché la condizione di repeat-mentre viene valutato alla fine di ogni iterazione. Il seguente esempio illustra questa differenza.

var c = 5 var d = 5 while c < d  print("c is smaller than d")  repeat  print("c is smaller than d")  while c < d

La dichiarazione di stampa del mentre il ciclo non viene mai eseguito, mentre quello del repeat-mentre il ciclo viene eseguito una volta.

In molti casi, per i loop possono essere riscritti come mentre loop, ed è spesso compito dello sviluppatore determinare il tipo di loop da utilizzare in una particolare situazione. Il seguente per e mentre i loop hanno lo stesso risultato.

per io in 0 ... <10  print(i)  var i = 0 while i < 10  print(i) i += 1 

Conclusione

C'è molto di più per controllare il flusso in Swift di quello che abbiamo trattato in questo articolo, ma ora hai una comprensione di base per continuare il tuo viaggio in Swift. Spero che questo tutorial ti abbia mostrato come l'implementazione del flusso di controllo di Swift è molto simile a quella di altri linguaggi di programmazione, ma con una svolta.

Nel resto di questa serie, faremo un uso maggiore dei costrutti di flusso di controllo di Swift e gradualmente otterremo una migliore comprensione delle sottili differenze tra Swift e lingue come Objective-C. Nella prossima puntata di questa serie, inizieremo ad esplorare le funzioni.

Se vuoi un modo rapido per iniziare a creare app con la lingua Swift, abbiamo un corso per questo!

Oppure guarda alcuni dei nostri altri tutorial e corsi sullo sviluppo di Swift e iOS!