Il tipo enum in Swift, o enumerations, è un particolare dato, simile per forma e non per utilizzo ad una classe, che permette di raggruppare più valori in una categoria comune. Definire una categoria significa che, i valori che si raggrupperanno dovranno avere una qualche sorta di correlazione tra di loro.

Ad esempio ipotizza di creare la categoria che rappresenta le regioni d’Italia. I suoi elementi non potranno che essere i nomi delle regioni. Se ti chiedessi quali sono le regioni d’Italia, tu cosa mi risponderesti?

Io le inizierei ad elencare più o meno così:

RegioniItalia {
  Sicilia
  Campania
  Lombardia
  Lazio
  ...
}

Con le conoscenze che hai acquisito fino ad ora dovresti essere in grado di rappresentare qualcosa del genere solo con gli array e dizionari o con una classe che al suo interno contenga un array:

var regioniItalia = ["Sicilia", "Lazio", "Campania", "Lombardia"]
 
//oppure
 
var regioniItalia1 = [
    1: "Sicilia",
    2: "Campania"
    // ecc
]

Il problema che si viene a creare è di tipo progettuale. Gli array e dizionari sono dei contenitori di informazioni quindi di per se non nascono come descrittori di qualcosa, mi spiego meglio!

Gli array o i dizionari nascono come contenitore i cui valori verranno utilizzati per eseguire delle operazioni all’interno dell’applicazione (lettura, scrittura, stampa ecc).

Gli enum non sono contenitori. Sono delle strutture di alto livello che ti permetteranno di utilizzare una sintassi più sicura per descrivere elementi che hanno una qualche sorta di relazione.

So che può sembrare strano (un po’ come la programmazione ad oggetti) ma cominceranno ad avere un senso non appena comincerai a creare applicazioni.

enum-linguaggio-swift

La sintassi

Un tipo enum del linguaggio swift si definisce tramite la parola chiave enum seguita dal nome della categoria. Dopo vanno fatte seguire le parentesi graffe:

enum RegioneItalia {
 //elementi
}

Ad ogni elemento si associa un case, più o meno come l’istruzione switch, grazie al quale sarà possibile accedere all’elemento:

enum RegioneItalia {
    case sicilia
    case sampania
    case lazio
    case lombardia
}

Più elementi possono anche essere inseriti tutti in una linea:

enum Pianeta {
    case mercurio, venere, terra, marte, giove, saturno, urano, nettuno
}

Dato che stiamo definendo un nuovo tipo è bene che esso abbia la prima lettera del nome minuscola.

Utilizzo

Un enum, alla stregua di una classe, definisce un nuovo tipo di dato. la variabile definita come tipo Enum può assumere solo e solamente i valori contenuti all’interno della sua definizione:

let unPianeta: Pianeta
unPianeta = Pianeta.terra

let unAltroPianeta: Pianeta = .venere // versione contratta

Nell’esempio che vedi sopra ho assegnato alla costante unAltroPianeta il valore dell’enum in maniera contratta. Cioè utilizzando solamente la notazione .nomeCase. Adesso, utilizzando uno switch puoi incanalare la variabile per controllarne perfettamente il comportamento:

var regione = RegioneItalia.sicilia

switch regione {
case .sicilia:
    print("La sicilia è ....")
case .campania:
    print("La campania è ....")
case .lazio:
    print("Il lazio è ....")
case .lombardia:
    print("La lombardia è ....")
}

Utilizzato uno dei valori dell’enum automaticamente verrà stampato la stringa corrispondente al case dello switch. Ti ricordo che l’istruzione switch vuole definiti tutti i valori dell’enum o in alternativa puoi ovviare al problema utilizzando il case default:

var unPianeta: Pianeta
unPianeta = .terra

switch unPianeta {
case .terra:
    print("La Terra è un posto abitabile")
default:
    print("Forse non è abitabile")
}

Valore e RawValue

Una delle particolarità degli enum è quella di poter assegnare un valore ad ogni case.

Essendo un enum un raggruppamento di valori costanti che si assomigliano tra loro è ovvio, almeno per me, immaginare che abbiano tutti lo stesso tipo di dato come tipo del valore. Eeee?

Se vuoi enumerare le regioni partendo, ad esempio, da sud verso nord, è facile pensare come la regione più a sud abbia 1 come valore e la regione più a nord 21.

Quindi, l’enum che rappresenta le regione si può trasformare così:

enum RegioneItalia: Int {
    case sicilia = 1
    case calabria = 2
    case basilicata = 3
    case puglia = 4
    //ecc
}

Viene fatto seguire al nome dell’enum il tipo di dato che dovrà avere il valore che rappresenterà i vari casi. Puoi assegnare solo un valore per case! 

Per poter leggere il valore associato al case puoi utilizzare la proprietà .rawValue.

 

var sicilia = RegioneItalia.sicilia
print(sicilia.rawValue) // stamperà 1

Considerazioni

Ho voluto trattare il tipo enum del linguaggio Swift in maniera semplice e veloce perché, in questo corso, non ci sono i presupposti per vedere le particolarità dell’enum e le sue infinite personalizzazioni.

Ad ogni modo, vedrai già un utilizzo reale dell’enum giù dalla prossima lezione dove sarà d’aiuto alla definizione dei possibili errori che potranno comparirà durante l’arco di vita dell’applicazione.

Buona Programmazione!

Changelog

  • 17/11/2016 – Aggiunto il changelog. Aggiornata la versione per il supporto a Xcode 8 e Swift 3.
Back to: Swift Tour: Corso gratuito linguaggio di programmazione Swift