Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Swift

Introduzione a Swift: Parte 1

by
Difficulty:BeginnerLength:LongLanguages:

Italian (Italiano) translation by Nicola Lamonaca (you can also view the original English article)

Durante il WWDC 2014, Apple ha introdotto uno dei più grandi aggiornamenti per iOS dal 2008 dal punto di vista degli sviluppatori. È stato introdotto HomeKit, HealthKit, CloudKit, e le Extensions, solo per citarne alcune. Ma la sorpresa più grande proveniente dal WWDC 2014 è stata senza dubbio l'introduzione di un linguaggio di programmazione totalmente nuovo, Swift.

Swift è un ottimo linguaggio di programmazione, costruito dalle fondamenta per essere efficiente e sicuro. Utilizza le stesse API che utilizza Objective-C. In altre parole, ciò che è possibile fare in Objective-C, si può fare in Swift. Esso introduce anche alcuni nuovi concetti che i programmatori con esperienza apprezzeranno, e altri che tratteremo in questa serie su Swift.

In questa serie, assumeremo che abbiate già familiarità con Objective-C. Nel primo articolo, parleremo della filosofia dietro Swift, della struttura dei files, e della sintassi. Nel secondo articolo, focalizzeremo l'attenzione su aspetti più avanzati della sintassi di Swift, come gli optionals e la gestione della memoria. Tenetevi pronti, sarà una bella avventura.

1. Filosofia

Per rendere Swift più comprensibile, nel corso di questi ultimi anni Apple si è concentrata su dei miglioramenti strutturali di Objective-C. Miglioramenti come blocchi di codice, definizione di dizionari e array letterali, ARC (Automatic Reference Counting), sono solo alcuni esempi delle novità che Apple ha aggiunto all'interno di Objective-C che agevolano la transizione a Swift.

Un importante pilastro della filosofia di Swift è l'inizializzazione del codice. Tutti gli oggetti e le variabili, quando definiti in Swift, devono essere prima inizializzati. In Swift, un oggetto o una variabile non inizializzati risulteranno in un errore a tempo di compilazione. Ciò assicura che un oggetto o una variabile abbiano sempre un valore. Un caso particolare in Swift si ha quando non è possibile assegnare nessun valore specifico. In questo caso particolare, la variabile prende il nome di optional. Tratteremo gli optionals nella seconda parte di questa serie.

Un altro importante pilastro è quello che possiamo definire "completezza dei cammini di selezione". Tutti i cammini di selezione, sia che si tratti di if o switch/case, devono coprire tutte le condizioni. In questo modo, nessuna porzione di codice può essere soggetta a fall-through, senza cioè che sia coperta da una qualche condizione. Se non si specifica una condizione in un costrutto di selezione verrà generato un errore a tempo di compilazione.

Un ultimo tratto della filosofia di Swift è la sua preferenza a maneggiare costanti, piuttosto che variabili. Swift definisce costanti e variabili nel modo seguente:

Nell'esempio sopra, viene utilizzata la keyword let per definire una costante, laddove invece la parola-chiave var definisce una variabile. Rendendo la definizione di costanti così agevole, Apple ne incoraggia l'uso ogni volta che ciò si renda possibile. Ciò porta ad avere del codice più sicuro in un ambiente multithread e ad un'ottimizzazione più efficiente dello stesso, poiché il compilatore sa che il valore di una costante non cambierà mai.

Ora, c'è molto di più all'interno di Swift che non sia qualche miglioramento sulla sintassi e sulla formattazione. Swift è stato costruito dalle fondamenta per risolvere molti fonti di crash proprie di C(++), e, inerentemente, anche di Objective-C. Problemi come:

  • indici di array fuori limite
  • dati non inizializzati
  • tipi di ritorno non controllati
  • accesso non controllato a puntatori
  • fall-through impliciti
  • errori di goto

In qualità di programmatore iOS e Android, so personalmente quanto più divertente sia programmare per iOS utilizzando Cocoa e UIKit. Questa serie vi mostrerà quantoancor più divertente può diventare programmare aggiungendo Swift a questo mix.

2. Struttura dei File

In Objective-C, abbiamo file di header (.h) e file di implementazione (.m). Si tratta di un'eredità che Objective-C ha ricevuto dal linguaggio C.

In Swift, una classe è definita in un singolo file di implementazione (.swift), che include tutte le definizioni e le implementazioni della classe. Questa è invece una reminiscenza di altri linguaggi, quali Java e C#.

Sparita la necessità di file di header fluttuanti e della direttiva #IFNDEF a monte dei file di header.

3. Sintassi

La prima cosa che noterete di Swift è la scomparsa del punto e virgola alla fine di ciascuna istruzione. In Swift, ogni riga è considerata un'istruzione e non c'è bisogno di aggiungere un punto e virgola e fine riga per indicarne una.

Sottolineo il non c'è bisogno, perché nulla vi vieta di aggiungere il punto e virgola alla fine delle istruzioni. Io continuo ad aggiungere comunque il punto e virgola alla fine di ciascuna istruzione perché ritengo migliori la leggibilità. Inoltre, è un'abitudine della quale non ci si libera facilmente se si à uno sviluppatore Cocoa da anni.

Un altro importante cambiamento in Swift è che le parentesi graffe sono obbligatorie per le istruzioni if. Questo significa niente più bug Heartbleed.

La sintassi può essere un argomento complesso da trattare. Swift ha tante sottigliezze che possono richiedere tanto tempo per essere discusse, ma non è questo l'obiettivo di tale articolo. Per brevit`, ci concentreremo sui cambiamenti che gli sviluppatori Objective-C potranno apprezzare.

4. Somiglianze con Objective-C

Cominciamo mostrando 3 frammenti di codice per illustrare alcune delle similarità con Objective-C. Questo vi aiuterà a comprendere il linguaggio Swift.

I programmatori Objective-C si accorgeranno che Swift prevede gli stessi identici costrutti di selezione e iterazione ai quali sono abituati, come if/else, cicli for e for..in, e il costrutto switch.

Swift include due operatori di range, ..< e ..., per specificare un intervallo di valori. Nel ciclo for in alto, utilizziamo l'operatore di range semi-chiuso, ..<, per specificare un intervallo di valori che include 1, 2, 3, e 4, ma esclude 5. L'altro operatore di range è l'operatore di range totalmente chiuso, .... Esso specifica un intervallo che include sia il valore a sinistra che quello a destra dell'operatore stesso. Per esempio, 1...5 specifica un range di valori da 1 a 5, estremi compresi.

5. Definire Variabili e Costanti

Rivediamo l'esempio di prima.

In Swift, definiamo le costanti con la parola-chiave let e le variabili con la parola-chiave var. I due punti, : , sono un indicatore per definire i tipi. Nell'esempio di sopra, abbiamo creato una costante e una variabile di tipo String.

Abbiamo anche inizializzato la costante e la variabile con una stringa. In Swift, le stringhe sono definite in stile C, proprio come in Objective-C, ma non sono precedute da un carattere @.

Objective-C è un linguaggio fortemente tipizzato, nel senso che il tipo di una variabile o di un parametro dev'essere sempre specificato. Anche Swift è un linguaggio fortemente tipizzato, ma è un po' più smart, poiché il compilatore sa come inferire il tipo di una variabile. Il compilatore si assicura anche che nessun casting incorretto di variabili avvenga al di fuori della vostra conoscenza o senza il vostro intervento.

Se riscriviamo l'esempio di sopra mettendo in funzione il meccanismo di inferenza dei tipi, allora il frammento di codice diventa:

In questo modo, il codice risulta molto più pulito. Il compilatore è abbastanza avanzato da accorgersi che someInt è un Int e someFloat è un Double.

6. Stringhe

Un modo per avere un'idea della potenza di un linguaggio è esplorare il modo in cui si comporta nella manipolazione delle stringhe. Objective-C ha tante funzioni e funzionalità che ci consentono di trattare stringhe, meglio che nella maggior parte dei linguaggi, ma a volte tendono ad essere poco immediate e confusionarie.

Cominciamo con un esempio in Objective-C. Per concatenare due stringhe in Objective-C, facciamo in questo modo:

In Swift, per concatenare una stringa ad un'altra, utilizziamo l'operatore +. È semplicissimo:

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

Possiamo iterare attraverso i caratteri di una stringa usando un costrutto for..in, come mostrato nell'esempio seguente. Possiamo utilizzare un loop for..in anche per iterare attraverso stringhe Unicode. È tanto facile:

Un'ultima cosa sulle stringhe prima di continuare è l'interpolazione delle stesse. In Objective-C, se vogliamo stampare una stringa contenente variabili, invochiamo [NSString stringWithFormat:]. In Swift, le variabili possono essere incluse direttamente nella stringa. Date un'occhiata all'esempio seguente:

Per utilizzare l'interpolazione delle stringhe, basta racchiudere la variabile o la chiamata di funzione tra parentesi tonde con un backslash, \, all'inizio: \(espressione).

7. Arrays e Dizionari

Array e Dizionario

Come programmatori Objective-C, avete già familiarità con array e dizionari. Anche Swift ha classi-collezione, alle quali aggiunge altre funzionalità.

Come si usano le collezioni in Swift? In Swift, le collezioni sono chiamate Array e Dizionario. Dichiarare un array in Swift è simile al dichiarare un array di letterali in Objective-C, utilizzando una coppia di parentesi quadre, [ ], ma senza il simbolo @ all'inizio.

Lo stesso discorso vale per i dizionari, con la differenza che, invece di usare parentesi graffe, si usano quelle quadre.

Mutabilità

Se un oggetto Array è equivalente ad un oggetto NSArray e un oggetto Dizionario è equivalente ad un oggetto NSDictionary, come creiamo degli array e dei dizionari mutable in Swift?

La risposta è molto semplice: dichiarando l'oggetto come una variabile. In altre parole, nell'esempio precedente, someArray è l'equivalente di un'istanza di NSArray e someOtherArray l'equivalente di un'istanza di NSMutableArray. Questo discorso si applica anche per i dizionari. Nell'esempio precedente, someDictionary è l'equivalente di un'istanza di NSDictionary e someOtherDictionary equivale ad un'istanza di NSMutableDictionary. Facile, vero?

Mentre in Objective-C array e dizionari possono contenere solo oggetti, in Swift le collezioni possono contenere tanto oggetti quanto dati di tipo primitivo, come integer e float. Un'altra importante differenza con Objective-C è che le collezioni in Swift sono tipizzate, esplicitamente o tramite inferenza di tipo eseguita a compile-time. Specificando il tipo degli oggetti contenuti in una collezione, Swift aggiunge un livello extra di sicurezza a tali collezioni.

Anche se possiamo omettere il tipo di una variabile al momento della sua dichiarazione, ciò non cambia il fatto che il compilatore assegnerà dei tipi agli oggetti in una collezione. L'inferenza di tipo aiuta a tenere il codice leggibile e leggero.

Possiamo ridichiarare gli oggetti Array e Dictionary dichiarati in precedenza come segue:

Il compilatore ispezionerà le collezioni durante la loro inizializzazione e inferirà il tipo corretto. In altre parole, esso si accorge che someArray e someOtherArray sono collezioni di oggetti di tipo String, mentre someDictionary e someOtherDictionary sono dizionari con chiavi di tipo String e valori di tipo Int.

Manipolazione delle Collezioni

Aggiungere un oggetto o un altro array ad un array è assai simile alla concatenazione delle stringhe, nel senso che, anche in questo caso, utilizziamo l'operatore +.

Manipolare i dizionari è ugualmente facile.

Collezioni Tipizzate

In precedenza, si à detto che le collezioni in Swift sono tipizzate, ma cosa significa? Se definiamo una collezione che contiene oggetti di tipo String, potete aggiungere solo oggetti di tipo String a quella collezione. In caso contrario verrà generato un errore.

Diamo un'occhiata ad un esempio per chiarire meglio. Definiamo una collezione di oggetti di tipo Car. Il seguente frammento di codice mostra la definizione della classe Car e di un mutable array, cars, contenente tre istanze di Car.

Dietro le quinte, il compilatore inferirà il tipo dell'array. Se vogliamo aggiungere una nuova istanza di Car alla collezione, possiamo semplicemente utilizzare l'operatore +, come mostrato di seguito.

In ogni caso, aggiungere un oggetto di tipo differente, risulterà in un errore.

Ciò ha il vantaggio aggiunto della sicurezza del tipo quando si prelevano oggetti dalle collezioni. Inoltre, elimina la necessità di effettuare il casting degli oggetti delle collezioni prima di utilizzarli.

Nel nostro esempio, un oggetto Car ha un metodo accelerate. Poiché le collezioni sono tipizzate, possiamo prelevare un oggetto dall'array ed immediatamente invocare un metodo su di esse, in una sola riga di codice. Non dobbiamo preoccuparci del tipo dell'oggetto, poiché la collezione contiene solo oggetti di tipo Car.

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

Infine, per iterare su un array, utilizziamo un loop for..in:

Anche per iterare su un dizionario, utilizziamo un loop for..in:

Come potete osservare, le collezioni tipizzate costituiscono una potente caratteristica del linguaggio Swift.

Conclusioni

Abbiamo già imparato un bel po' sul linguaggio Swift e dovreste prendervi del tempo per approfondire il tutto. Vi raccomandiamo di scaricare Xcode 6 il prima possibile e di cominciare ad applicare ciò che avete imparato in questo articolo nel nuovo Playground di Xcode.

Questo articolo termina qui. Nella prossima puntata di questa serie, daremo un'occhiata alle tuple, alle funzioni, alle closures, alle classi, e, ultimo ma non ultimo, agli optionals. Imparerete anche come funziona la gestione della memoria in Swift. Restate sintonizzati.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.