Variabili e costanti
La definizione di una variabile in Swift avviene utilizzando la parola riservata var
, seguita dal nome e dal tipo di dati che essa conterrà:
var nome: String
Si noti che non è necessario utilizzare il punto e virgola al termine delle istruzioni in Swift, e questa è in generale una buona norma suggerita da Apple stessa, per rendere il codice più leggibile.
La variabile così definita, tuttavia, non può essere immediatamente utilizzata, in quanto il compilatore richiede che ogni variabile sia inizializzata prima dell'uso. È possibile dunque definire e assegnare un valore iniziale ad una variabile in un'unica istruzione:
var nome: String = "Antonio"
In questo caso, possiamo anche omettere il tipo:
var nome = "Antonio"
Ciò si deve alla capacità di Swift di determinare automaticamente il tipo di dato della variabile dal valore assegnatole. Questa caratteristica del linguaggio si chiama type inference e la vedremo utilizzata estensivamente in altri costrutti.
In maniera del tutto simile, se vogliamo definire una costante, utilizziamo la parola riservata let
:
let url = "http://www.html.it"
Una volta assegnato un valore ad una costante, questo non può più essere modificato. Tentare di riassegnare un nuovo valore genererà un errore di compilazione. In questo caso, url
è di tipo String
.
Un'altra buona norma è quella di preferire l'utilizzo di costanti alle variabili, in quanto questo rende l'intento dello sviluppatore più chiaro a chi legge, ed il compilatore Swift sarà in grado di effettuare ulteriori ottimizzazioni in fase di compilazione.
Tipi di dati
Swift è un linguaggio fortemente tipizzato: il compilatore deve essere sempre in grado di determinare, sia esplicitamente che implicitamente con il meccanismo di type inference, il tipo di dato di variabili, costanti, argomenti di funzione e valori di ritorno in ogni istante, pena il fallimento della compilazione. Swift è dunque un linguaggio type safe, caratteristica che permette di prevenire tutta una serie di errori di esecuzione già durante la compilazione.
Negli esempi precedenti abbiamo visto il tipo String
. Vediamo altri tipi di dati comuni in Swift:
var currentValue: Int = 35
var temperature: Float = 24.5
let pi: Double = 3.14159
var unCarattere: Character = "a"
var isValid: Bool = true
Analizziamoli brevemente.
Numeri interi
Swift fornisce diversi tipi per rappresentare i numeri interi, a seconda della precisione e del supporto o meno dei numeri con segno (positivi e negativi). Di seguito un elenco dei tipi con segno e senza segno (Unsigned):
Int8, Int16, Int32, Int64
UInt8, UInt16, UInt32, UInt64
Oltre a questi, sono disponibili anche Int
e UInt
. Di fatto Int
è il tipo più comunente utilizzato e Apple stessa ne suggerisce l'uso quando non vi è esplicita necessità di specificare i bit da allocare per la variabile. La dimensione di Int
e UInt
viene determinata automaticamente dalla piattaforma in cui il codice verrà eseguito (ad esempio, gli Int
sono a 64bit a partire da iPhone 6 in poi, con iOS >= 8).
Numeri in virgola mobile
Per rappresentare e manipolare numeri decimali, Swift offre i tipi Double
e Float
. Sono entrambi capaci di gestire numeri con segno. Un Double
permette di rappresentare un numero in virgola mobile a 64bit, mentre un Float
è limitato a 32bit.
Se il tipo non viene specificato in fase di definizione di una variabile (o costante), il meccanismo di type inference gli assegna il tipo Double
.
Conversioni di tipo
Per convertire un intero in virgola mobile e viceversa è possibile utilizzare il nome del tipo di destinazione come se fosse una funzione, passando come parametro il valore da convertire. Vedremo nelle lezioni seguenti, che si tratta di fatto di un inizializzatore:
let base = 3 // tipo inferito: Int
let altezza = 5.2 // tipo inferito: Double
var area = base * altezza // errore, non valido perchè base e altezza hanno un tipo diverso
var area = Double(base) * altezza // corretto, operandi dello stesso tipo ed il risultato ` un Double
// conversione da Double a Int
let altezzaApprossimata = Int(altezza) // troncato a 5
Nel caso di conversione da virgola mobile a intero, l'eventuale parte decimale viene automaticame troncata (esistono funzioni apposite per l'arrotondamento o il floor).
Booleani
Il tipo Bool
prevede solo due valori logici true
e false
, particolarmente utili nelle istruzioni condizionali:
var isValid = true
if isValid {
print("Operazione valida")
}
Caratteri e stringhe
Accenniamo qui brevemente a questi ultimi tipi di dati molto comuni, ma tratteremo nel dettaglio le stringhe in una delle prossime lezioni.
Possiamo definire un variabile (o costante) di tipo carattere con:
let punto: Character = "." // possiamo omettere il tipo naturalmente
Una stringa non è altro che una collezione ordinata di caratteri:
for carattere in "Hello world!" {
print(carattere)
}
Per inizializzare una stringa con un valore predefinito, usiamo un letterale, cioè una sequenza di testo circondata da doppie virgolette:
let saluti = "Ciao a tutti"
L'operatore "+" ci consente di concatenare una o più stringhe. Nel caso volessimo concatenare un carattere ad una stringa, dobbiamo convertirlo esplicitamente, con uno degli inizializzatori delle stringhe, creando una nuova stringa a partire da un carattere:
var saluto = "Buongiorno"
let virgola: Character = ","
var nome = "Antonio"
var salutoCompleto = saluto + String(virgola) + " " + nome
Swift introduce un potente meccanismo di interpolazione che consente di creare stringhe a partire da un mix di letterali, costanti, variabili ed espressioni. Ogni elemento da inserire nella stringa finale deve essere circondato da parentesi tonde ( ) precedute da un carattere di backslash \:
var salutoCompleto = "\(saluto), \(nome)"
var base = 3
var altezza = 5
var areaDelQuadrato = "L'area del quadrato di base \(base)cm e altezza \(altezza)cm è pari a \(base * altezza)cm quadrati"
Mentre in Objective-C le stringhe sono istanze delle classi NSString e NSMutableString, e le variabili che le contengono sono delle referenze, in Swift le stringhe sono value type: vengono, cioè, passate per valore. Questo implica che l'assegnazione di una variabile stringa ad un'altra variabile, o il passaggio come parametro ad una funzione o metodo crea una copia della stringa originale.