Dopo aver presentato i tipi di dato fondamentali e gli optional, andiamo a conoscere altri due tipi molto comuni inclusi nella libreria standard di Swift: gli Array e i Dizionari.
Array
Un array viene definito e inizializzato con una sintassi molto simile a quella di altri linguaggi di programmazione:
var strumentiMusicali = ["Pianoforte", "Chitarra", "Clarinetto"]
Se andiamo a ispezionare il tipo assegnato a strumentiMusicali
(Option+Click su Xcode) per il meccanismo di type inference, otterremo:
var strumentiMusica: [String]
Su Swift, dunque, gli elementi di un array devono essere tutti dello stesso tipo.
Per accedere ad un elemento dell'array, usiamo l'operatore subscript
, indicando l'indice dell'elemento a cui siamo interessati (il primo elemento ha indice 0):
strumentiMusicali[0] // "Pianoforte"
In maniera simile, possiamo utilizzare lo stesso operatore per modificarne un elemento:
strumentiMusicali[1] = "Basso elettrico"
Se il nostro array è stato definito come variabile, è possibile modificarne il contenuto, aggiungendo uno o più elementi:
strumentiMusicali.append("Arpa") // aggiunta di un singolo elemento
strumentiMusicali += ["Sax"] // aggiunta di un array con singolo elemento
// appendere un nuovo array in coda
strumentiMusicali.extend(["Tamburo", "Gran Cassa", "Piatti"])
// concatenazione di array
var percussioni = ["Tamburo", "Gran cassa", "Piatti"]
strumentiMusicali = strumentiMusicali + percussioni
Swift fornisce anche l'operatore Range
che ci permette di selezionare un numero contiguo di elementi compresi tra due indici:
strumentiMusicali[0...3] // restituisce un array con i primi 4 elementi
strumentiMusicali[1..<3] // restituisce un array con il secondo e terzo elemento
Il secondo esempio mostra un range aperto, dove l'elemento all'indice finale non è incluso.
È possibile inserire un nuovo elemento ad una data posizione. L'array aumenterà di dimensioni e gli elementi presenti verranno fatti slittare di una posizione a destra:
strumentiMusicali.insert("Oboe", at: 1)
strumentiMusicali.count // restituisce il numero di elementi di un array
In maniera simile, quando rimuoviamo un elemento, gli elementi restanti vengono fatti slittare a destra:
// rimozione del 4 elemento
strumentiMusicali.remove(at: 3)
Il metodo remove(at:)
restituisce, inoltre, l'elemento rimosso.
Possiamo anche definire un array costante, usando let
:
let marcheAuto = ["BMW", "Audi", "Fiat", "Skoda"]
Così facendo, però, non sarà possibile modificare, aggiungere o estendere l'array.
Infine, vediamo qual è la notazione per definire una variabile di tipo array:
var temperatureMinime: [Double]
var temperatureMassime: Array<Double>
Per definire e inizializzare un array vuoto in un'unica istruzione, possiamo invece procedere come segue:
var ottoni = [String]()
var archi = Array<String>()
Dizionari
I dizionari ci permettono di creare una lista (non ordinata) di coppie chiave-valore. Sono il secondo tipo collezione più diffuso in Swift.
La creazione di un dizionario con i letterali ha una sintassi molto più intuitiva rispetto a quella usata in Objective-C:
var auto = ["marca": "bmw", "modello": "X3", "colore": "blu", "posti": "5"]
Se ispezioniamo il tipo assegnato dal compilatore ad auto
, otterremo:
var auto: [String : String]
Anche per i dizionari, il tipo di tutte le chiavi e di tutti i valori devono essere identitici.
Per definire un dizionario vuoto, usiamo la seguente sintassi:
var nuovoDiz = Dictionary<T, U>()
var nuovoDiz = [T : U]()
Nelle righe di codice precedenti, T
è il tipo di dati da assegnare alla chiave, ed U
è quello da assegnare al valore.
Data una chiave, per accedere al rispettivo valore, usiamo nuovamente l'operatore di subscript
:
auto["marca"]
print(auto["marca"])
Si noti che viene restitutito un tipo optional, del quale dovrà essere effettuato l'unwarp tramite l'operatore di force-unwrapping:
auto["marca"]!
In alternativa possiamo usare il meccanismo di optional binding:
if let marca = auto["marca"] {
println(marca)
}
Il motivo per cui viene restituito un optional è facilmente spiegabile: quando viene richiesto il valore di una chiave che non esiste, Swift restituisce nil
:
auto["proprietario"] // restituisce nil, permesso perchè l'operatore subscript su un dizionario restituisce un tipo opzionale
Se vogliamo aggiungere un nuovo elemento ad un dizionario, usiamo ancora l'operatore subscript
:
auto["anno_di_acquisto"] = "2014"
Una sintassi alternativa più esplicita è quella di usare il metodo updateValue:forKey
:
auto.updateValue("Antonio", forKey: "proprietario")
Entrambe le precendenti sintassi possono essere utilizzate per modificare il valore corrispondente ad una data chiave:
auto["anno_di_acquisto"] = "2016"
auto.updateValue("anno_di_acquisto", forKey: "2015")
La rimozione di un elemento (chiave-valore) da un dizionario si ottiene con il metodo removeValue(forKey:)
:
auto.removeValue(forKey: "proprietario")
auto.removeValue(forKey: "chiave che non esiste")
Questo metodo ritorna il valore della chiave (sempre opzionale) o nil
nel caso questa non esista.
È disponibile anche la proprietà count
che ritorna il numero di elementi del dizionario, come per gli array:
// numero di coppie nel dizionario
auto.count
Infine, possiamo estrarre separatamente l'insieme di tutte le chiavi e di tutti i valori, usando rispettivamente le proprietà keys
e value
. Queste tuttavia restituiscono delle collezioni particolari poco manipolabili direttamente. Tipicamente esse vengono convertite in array con la seguente sintassi:
// estrazione delle chiavi e dei valori separatament
let chiavi = Array(auto.keys)
let valori = Array(auto.values)
o usate nei cicli (che vedremo nella prossima lezione):
for k in auto.keys {
print(k)
}
for v in auto.values {
print(v)
}
Il Playground completo con tutti gli esempi usati finora è allegato a questa lezione, nonchè disponibile a questo link.