Italian (Italiano) translation by Luca Menozzi (you can also view the original English article)
Apple introdusse il linguaggio di programmazione Swift durante la sua annuale conferenza per sviluppatori nel 2014, con grande sorpresa della comunità. L'azienda fa le cose seriamente con Swift, non è un esperimento. Lo scopo di questo linguaggio è di alimentare la prossima generazione di applicazioni per le piattaforme Apple.
Prerequisiti
Programmazione
Non è possibile trattare le basi della programmazione e imparare Swift in uno o due articoli. Do quindi per scontato che tu abbia già un po' di esperienza. Ruby, PHP o Javascript sono buoni punti di partenza per imparare Swift. Se arrivi dallo sviluppo web, non dovresti trovare grosse difficoltà ad impararne le basi leggendo i prossimi due articoli.
Swift
Nei prossimi due articoli ti mostrerò la potenza dei playground, una funzionalità introdotta con Xcode 6. Ci occuperemo anche delle basi del linguaggio Swift, come le variabili, le costanti e i tipi di dati, inclusi i set, gli array e i dictionary.
Imparerai anche le basi di classi e strutture. Nel prossimo articolo, ci focalizzeremo sulle closures, sulle funzioni, sui protocolli e sul controllo di accesso. Questo dovrebbe fornirti informazioni sufficienti sul linguaggio per poter completare la serie.
Objective-C
In senso stretto, C e Objective-C non sono necessari se sei interessato allo sviluppo sulla piattaforma Apple. Detto ciò, la maggior parte dei framework che useremo per sviluppare applicazioni iOS sono scritti in C e Objective-C. Questo significa che, occasionalmente, parleremo di questi due linguaggi. Non ti preoccupare, però, mi assicurerò che tu capisca tutto ciò che è essenziale per tenerti sul giusto binario per raggiungere il tuo obiettivo di diventare uno sviluppatore iOS.
Xcode e Swift
Per tutta questa serie, userò Xcode 7.1 e Swift 2.1. Se stai usando una vecchia versione di Xcode, tieni a mente che non potrai lavorare con Swift 2.1. Swift continua a cambiare molto rapidamente e la sintassi evolve con ogni versione del linguaggio. Io consiglio, perciò, di usare Xcode 7.1 che supporta Swift 2.1.
1. I Playground
Nel 2014, Apple introdusse i playground come parte di Xcode 6. I playground sono ottimi per imparare Swift. Con i playground, puoi concentrarti sul codice che stai scrivendo invece di impantanarti con le preferenze del progetto, i file e le cartelle.
Creiamo un playground per iniziare a imparare le basi di Swift. Lancia Xcode 7.1 e scegli New > Playground... dal menu File. I playground supportano OS X, iOS e tvOS. Imposta Platform su iOS e dagli, come nome, Swift in a Nutshell.



Di' a Xcode dove vuoi salvarlo e clicca su Create. A prima vista, un playground sembra un semplice file con estensione .playground, ma, in realtà, è una cartella con diversi file. Fortunatamente, non è una cosa di cui dobbiamo preoccuparci. E' molto più semplice avere a che fare con un playground che con un progetto Xcode con dozzine di file e cartelle.



L'interfaccia utente è semplice e pulita. Puoi vedere l'editor di codice sulla sinistra e l'output sulla destra. Xcode ha già inserito nel playground tre righe di codice. La prima linea dovrebbe esserti familiare, se hai letto il tutorial precedente.
1 |
//: Playground - noun: a place where people can play
|
La linea inizia con un doppio slash, //
, che indica al compilatore di ignorare questa linea. I commenti su più righe iniziano con /*
e terminano con */
.
1 |
/*
|
2 |
This is a longer
|
3 |
comment spanning
|
4 |
multiple lines.
|
5 |
*/
|
Xcode ha anche aggiunto una istruzione per il framework UIKit. UIKit è il framework più importante per lo sviluppo iOS. Definisce gli elementi costitutivi con cui le applicazioni iOS sono realizzate. In Swift, importare un framework è molto semplice: si usa la parola chiave import
seguita dal nome del framework, UIKit.
1 |
import UIKit |
L'ultima linea potrebbe ricordarti JavaScript. Usiamo la parola chiave var
per dichiarare una variabile, str
, e assegniamo un valore ad essa, "Hello, playground"
. Questo esempio mostra da subito una caratteristica chiave di Swift: la type inference (la deduzione del tipo di dato).
1 |
var str = "Hello, playground" |
L'esempio precedente è un po' fuorviante. Potresti pensare che Swift sia un un linguaggio con tipizzazione debole: in realtà, è vero il contrario. La variabile str
è del tipo String
. Swift è abbastanza intelligente da dedurre il tipo di str
osservando il valore che le viene assegnato.
L'esempio seguente è equivalente. In questo esempio, specifichiamo in maniera esplicita il tipo della variabile str
. I due punti che seguono il nome della variabile possono essere letti come "è del tipo".
1 |
var str: String = "Hello, playground" |
2. Variabili e Costanti
Swift definisce anche la parola chiave let
. Questa parola chiave è utilizzata per dichiarare una costante. Il linguaggio Swift incoraggia all'uso delle costanti, ove possibile. Se il valore della variabile non cambia per il suo ciclo di vita, dovrebbe essere una costante. Come il nome suggerisce, una volta che ad una costante è stato dato un valore, non può essere modificato. Il seguente esempio chiarisce il concetto.



Nell'esempio precedente, dichiariamo una costante message
e le assegniamo un valore. Qualche linea più in basso, assegniamo un nuovo valore a message
. Dato che stiamo cercando di modificare il valore di message
, il compilatore genera un errore. Fortunatamente, suggerisce anche come risolvere il problema: trasformando la costante message
in una variabile.
3. Tipi di Dato
Swift definisce una vasta gamma di tipi di dato, ma diamo un'occhiata ai più comuni a cui andrai incontro.
Booleani
Iniziamo con un tipo semplice, Bool
. In Swift, i booleani sono altrettanto semplici e facili da usare come lo sono negli altri linguaggi. L'esempio seguente è probabilmente così semplice come sembra.
1 |
let myBool = true |
2 |
var notTrue = false |
3 |
notTrue = true |
Numeri
I numeri sono rappresentati da Int
, UInt
, Float
o Double
. Esistono altri tipi di dato per salvare i valori numerici, ma questi sono i più comuni. Questi tipi sono simili a quelli che trovi negli altri linguaggi di programmazione.
Dato che Swift è un linguaggio fortemente tipizzato, dovrai affrontare le conversioni dei tipi, di tanto in tanto. Per esempio, non è possibile moltiplicare un Int
per un Float
. Dai un'occhiata all'esempio qui di seguito per capire meglio il problema.



A prima vista potrebbe sembrare un grande limite di Swift. In realtà questo comportamento è innato nei linguaggi fortemente tipizzati. Fortunatamente, la soluzione è semplice, come puoi vedere qui di seguito.



Anche se può sembrare che stiamo convertendo a
al tipo Float
, non è quello che sta accadendo. Stiamo creando o inizializzando un Float
usando il valore memorizzato in a
.
Ci sono due modi per creare una variabile o una costante: sintassi letterale o sintassi di inizializzazione. Le costanti a
e b
sono create usando la sintassi letterale. La variabile str
, di cui abbiamo parlato prima, è un altro esempio di sintassi letterale.
Per creare un Float
dal valore memorizzato in a
, usiamo una sintassi di inizializzazione. Creiamo il Float
usando il nome del tipo, Float
, seguito da due parentesi e passando a
come parametro.
Stringhe
Abbiamo già incontrato qualche stringa in questo tutorial. Una stringa non è nient'altro che una sequenza di caratteri. Infatti è possibile accedere alla collezione di caratteri, come mostrato nell'esempio qui di seguito.
1 |
let city = "Brussels" |
2 |
let chars = city.characters |
Nell'esempio precedente, abbiamo usato una stringa letterale. Il prossimo esempio illustra come usare l'inizializzatore del tipo String
. La sintassi è identica a quella che abbiamo visto in un esempio precedente relativo ai numeri e alla conversione di tipo.
1 |
let country = String("Belgium") |
Le Collection
La libreria standard di Swift definisce tre comuni tipi di collection: Array
, Dictionary
e Set
. Questi tipi di collection richiedono poca spiegazione se hai confidenza con Objective-C o qualsiasi altro linguaggio di programmazione. In alcuni linguaggi, i dictionary sono anche conosciuti come hash e gli array come liste. Comunque sia, l'idea che c'è dietro è la stessa.
1 |
let myArray = [1, 2, 3, 4, 5] |
2 |
let myDictionary = ["One": 1, "Two": 2, "Three": 3] |
3 |
let mySet = Set(["One", "Two", "Three", "Four", "Five"]) |
L'array e il dictionary vengono inizializzati usando una sintassi letterale. Dato che il tipo Set
non ha una sintassi letterale, dobbiamo usare la sintassi di inizializzazione per creare la costante mySet
.
Ho già menzionato che Swift è un linguaggio fortemente tipizzato e questo ha conseguenze sui tipi di collezioni. Il prossimo esempio chiarisce questo concetto. Iniziamo creando una variabile arr1
di tipo [Int]
. Ciò comporta che arr1
può contenere solo valori di tipo Int
.



La seconda e la terza istruzione lo confermano. Se si fa l'append di un intero, funziona correttamente, ma se lo si fa di una stringa, il compilatore restituisce un errore. Il compilatore cerca di convertire "Two"
in un Int
, ma non ci riesce. Il risultato è un errore.
L'esempio seguente rende la situazione ancora più confusa. Perchè il compilatore non si lamenta se l'array contiene valori di tipi differenti? Il motivo ti sorprenderà. La costante arr2
è del tipo [AnyObject]
.
1 |
let arr2 = [1, 2, 3, "Four", "Five"] |
Any
e AnyObject
La libreria standard di Swift definisce due tipi particolari, Any
e AnyObject
. Il tipo Any
può rappresentare qualsiasi tipo, mentre il tipo AnyObject
può rappresentare qualsiasi classe o struttura. Se ti senti confuso, sappi che è perfettamente normale. Swift è stato progettato per essere fortemente tipizzato e sempra che Any
e AnyObject
siano una minaccia alla sicurezza del tipo in Swift.
Il motivo della presenza di Any
e AnyObject
è principalmente per ragioni di compatibilità. Ho già menzionato che la maggior parte dei framework usati per lo sviluppo di Cocoa sono scritti in C e Objective-C. Quest'ultimo definisce il tipo id
, che rappresenta qualsiasi oggetto. Per essere sicuri che Swift e i framework Cocoa possano lavorare insieme, la libreria standard di Swift contiene i tipi Any
e AnyObject
. Ne sapremo di più quando inizieremo a lavorare con i framework Cocoa.
4. Classi e Strutture
Classi
Se hai confidenza con la programmazione orientata agli oggetti, allora dovresti già conosscere le classi. Sono abbastanza ordinarie in Swift. Dai un'occhiata all'esempio seguente nel quale definiamo una classe, Boat
, con due proprietà, speed
e lifeboats
, e un metodo, deployLifeboats()
.
1 |
class Boat { |
2 |
|
3 |
var speed: Float = 0 |
4 |
var lifeboats: Int = 2 |
5 |
|
6 |
func deployLifeboats() { |
7 |
// ...
|
8 |
}
|
9 |
|
10 |
}
|
Inizializzare e modificare un'istanza della classe Boat
è semplice, come puoi osservare qui di seguito. Richiamare un metodo su un'istanza non richiede pratiche di magia. Le basi delle classi Swift sono semplici da imparare. Giusto?
1 |
var boat = Boat() |
2 |
|
3 |
boat.speed = 10.5 |
4 |
boat.lifeboats++ |
5 |
|
6 |
boat.deployLifeboats() |
Strutture
Creeremo ora una struttura che assomiglia sorprendentemente alla classe Boat
e andiamo a scoprire cosa differenzia le classi dalle strutture, in Swift.
1 |
struct Ship { |
2 |
|
3 |
var speed: Float = 0 |
4 |
var lifeboats: Int = 2 |
5 |
|
6 |
func deployLifeboats() { |
7 |
// ...
|
8 |
}
|
9 |
|
10 |
}
|
L'esempio seguente evidenzia la più importante differenza tra le classi e le strutture.



Questo esempio evidenzia che le classi sono passate per riferimento mentre le strutture sono passate per valore. Cosa significa? Abbiamo inizializzato l'istanza di Boat
, l'abbiamo assegnata a boat1
e abbiamo impostato la proprietà speed
a 11.0
. Abbiamo assegnato boat1
a boat2
. Vuol dire che boat2
ha un riferimento a boat1
. Sia boat1
che boat2
puntano alla stessa istanza di Boat
. Il risultato è che impostando la proprietà speed
di boat2
, modifica anche la proprietà speed
di boat1
.
Questo non vale per le strutture. Ripetiamo gli stessi step usando la struttura Ship
. Il risultato finale però è differente. Assegnando ship1
a ship2
, il valore di ship1
è copiato e memorizzato in ship2
. Di conseguenza, ship1
e ship2
puntano a oggetti differenti, differenti istanze della struttura Ship
. Questo è un concetto molto importante da assimilare perciò assicurati di comprenderlo prima di continuare.
Conseguenze
Ti sono già stati presentati i comuni tipi di dato definiti nella libreria standard di Swift. Ciò a cui non ho ancora accennato in questa chiacchierata è che ogni tipo di dato in Swift, di cui abbiamo parlato finora, è una struttura.
Ad esempio, ogni tipo collezione, in Swift, è una struttura. Ogni tipo numero è una struttura. Questo è importante saperlo e capirlo, specialmente se arrivi da un linguaggio che passa alcuni di questi tipi per riferimento, come Ruby o Objective-C.
Ulteriori Differenze
Ci sono numerose altre differenze che contraddistinguono classi e strutture, in Swift. Le classi supportano l'ereditarietà, mentre le strutture no. Nell'esempio seguente, definiamo una classe Speedboat
che eredita dalla classe Boat
. La classe Boat
è la classe padre, o superclasse, di Speedboat
.
1 |
class Speedboat: Boat { |
2 |
|
3 |
}
|
4 |
|
5 |
var speedboat = Speedboat() |
6 |
|
7 |
speedboat.speed = 100.0 |
8 |
speedboat.lifeboats = 0 |
9 |
speedboat.deployLifeboats() |
Poiché Boat
è la classe padre di Speedboat
, Speedboat
eredita le proprietà e i metodi definiti nella classe Boat
. Il prossimo esempio illustra questo concetto. Anche se l'implementazione della classe Speedboat
è vuota, l'istanza di Speedboat
, myBoat
, ha le proprietà speed
e lifeboats
come anche il metodo deployLifeboats()
.
Una differenza più sottile che distingue le classi dalle strutture è il controllo del tipo durante l'esecuzione. Puoi controllare il tipo dell'istanza di una classe durante l'esecuzione mentre questo non è possibile per le istanze delle strutture.
5. Opzionali
Gli opzionali sono una parte integrante del linguaggio Swift. Scopriamo cosa sono gli opzionali e perché sono così importanti. Una variabile, prima che possa essere usata, deve essere inizializzata. Dai un'occhiata all'esempio qui di seguito per capire cosa significa.
1 |
var str: String |
2 |
|
3 |
str.isEmpty |
Se sei solito lavorare con le stringhe in altri linguaggi di programmazione, allora potresti essere sorpreso del fatto che il compilatore generi un errore. Vediamo cosa dice l'errore.



In molti linguaggi, le variabili hanno un valore di default iniziale. In Objective-C, ad esempio, la stringa, nel seguente snippet di codice, è uguale a nil
.
1 |
NSString *newString; |
Cos'è un Opzionale?
Swift usa gli opzionali per sintetizzare un concetto importante: una variabile, o una costante, ha un valore oppure non ce l'ha. E' così semplice in Swift. Per dichiarare una variabile o una costante come opzionale, aggiungiamo un punto interrogativo dopo il tipo di variabile, o costante.
1 |
var str: String? |
La variabile str
non è più di tipo String
. E' ora del tipo String
opzionale. Questa è una cosa importante da capire. La conseguenza è che non interagiamo più direttamente con il valore di str
. Il valore è memorizzato in modo sicuro nell'opzionale e dobbiamo chiedere all'opzionale il valore che incapsula.
Apertura Forzata
Una strada per accedere al valore di un opzionale è la sua apertura forzata. Possiamo accedere al valore di str
aggiungendo un !
al nome della variabile.
1 |
var str: String? |
2 |
|
3 |
str = "Test" |
4 |
|
5 |
println(str!) |
E' importante che tu sia certo della presenza di un valore nell'opzionale quando esegui l'apertura forzata. Se forzi l'apertura di un opzionale che non contiene un valore, Swift genera un errore e l'applicazione va in crash.



Vincolo Opzionale
Esiste una strada più sicura per accedere al valore di un opzionale. L'esempio seguente mostra come possiamo accedere in sicurezza al valore memorizzato in str
, di tipo String?
.
1 |
var str: String? |
2 |
|
3 |
if str != nil { |
4 |
println(str!) |
5 |
} else { |
6 |
println("str has no value") |
7 |
}
|
Innanzitutto controlliamo che str
sia uguale a nil
, prima di stampare il suo contenuto. In questo esempio, str
non ha un valore. Ciò significa che non sarà aperta forzatamente per sbaglio.
Esiste un approccio più elegante, conosciuto come optional binding. Nell'esempio qui di seguito, assegniamo il valore memorizzato nell'opzionale ad una costante temporanea. Il valore dell'opzionale str
è legato alla costante strConst
e reso disponibile nella clausola if
del blocco if
. Questo approccio funziona anche per i blocchi while
.
1 |
var str: String? |
2 |
|
3 |
str = "Test" |
4 |
|
5 |
if let strConst = str { |
6 |
println(strConst) |
7 |
} else { |
8 |
println("str has no value") |
9 |
}
|
Cos'è nil
?
Se arrivi da un linguaggio come l'Objective-C, saprai certamente cos'è nil
. In Objective-C, nil
è un puntatore ad un oggetto che non esiste. Swift definisce nil
un po' diversamente ed è importante che tu capisca la differenza.
In Swift, nil
significa assenza di valore, nessun valore. Mentre in Objective-C nil
è applicabile solo agli oggetti, in Swift nil
può essere usato per qualsiasi tipo.
Ti Sei Dimenticato il Punto e Virgola?
Hai per caso notato che non abbiamo usato punti e virgola negli esempi di questo tutorial? In Swift, non c'è bisogno di usare il punto e virgola, perché il compilatore è abbastanza intelligente da capire quando un'istruzione termina e ne inizia un'altra. Se senti la mancanza del punto e virgola, puoi metterlo comunque. Tieni a mente, tuttavia, che la guida del linguaggio raccomanda di non metterlo.
Conclusioni
Abbiamo solo scalfito la superficie, in questo tutorial, ma possiedi già delle conoscenze basilari di Swift. Nel prossimo tutorial, esploreremo altri componenti chiave del linguaggio: closure e funzioni. E discuteremo anche di protocolli e di controllo di accesso.
Per qualsiasi domanda o commento, puoi lasciarli qui di seguito o sul mio account Twitter.