Vai al contenuto

STRUTTURE

Cosa imparerò:

  • Come creare modelli con le strutture
  • Quando usare la func mutating
  • Le proprietà computate
  • Gli osservatori

Le strutture ci permettono di creare nostri tipi di dato, combinando una o più variabili, e permettendo di scrivere anche dei metodi.

La definiamo con la keyword struct, e dandole un nome unico, per convenzione con l’iniziale in maiuscolo per differenziarla dalle variabili e costanti.

struct Persona {
    var nome: String
    var cognome: String
}

Andremo a creare un’istanza di tipo Persona a cui assegneremo i valori:

var mary = Persona(nome: "Mary", cognome: "Winchester")

Accederemo alle proprietà della struct con la sintassi del punto:

print("Ciao \(mary.nome) \(mary.cognome)")

Output

Ciao Mary Winchester

Possiamo aggiungere funzionalità alla struct:

struct Persona {
    var nome: String
    var cognome: String 
    func saluta() {
        print("Ciao \(nome) \(cognome)")
    }
}

Per richiamare la funzione utilizzeremo la sintassi del punto sull’istanza:

mary.saluta()

Output

Ciao Mary Winchester

Quando creiamo delle struct possiamo creare un inizializzatore personalizzato che assegni valori alle proprietà.

Con il self. si fa riferimento alla variabile creata in precedenza:

struct Persona {
    var nome: String
    var cognome: String 
    init(nome: String) {
        self.nome = nome
        self.cognome = "Smith"
    }

    func saluta() {
        print("Ciao \(nome) \(cognome)")
    }
}

Quando creiamo un’istanza di questo tipo avremo la possibilità di scegliere quale init utilizzare, quello di default (memberwise initializer) per inserire tutti i valori o quello custom:

let persona = Persona(nome: "John")
        print("Ciao \(persona.nome) \(persona.cognome)")

Output

Ciao John Smith

Nel caso dovessi aggiornare il valore di una proprietà all’interno di una struct in un metodo dell’istanza, possiamo aggiungere la keyword mutating prima della funzione.

struct Odometer {
    var count: Int = 0
    mutating func aumenta() {
        count += 1
    }
}

Se non viene inserito mutating ci sarà un errore, i metodi delle struct, essendo value types, non possono modificare self o le sue proprietà.

Possiamo sfruttare una funzionalità che consente ad una proprietà di eseguire una logica che restituisce un valore calcolato, sono le cosiddette proprietà computate.

struct Rettangolo {
    var base: Double
    var altezza: Double
    var area: Double {
        return base * altezza
    }
}
let rettangolo = Rettangolo(base: 5.0, altezza: 3.0)
print(rettangolo.area)

Output

15.0

Possiamo anche utilizzare degli osservatori sulle proprietà che vengono chiamati ogni volta che viene aggiornato il valore di una proprietà. Sono due blocchi di codice che possono essere definiti su ogni proprietà della struct.

struct ContatorePassi {
    var totalePassi: Int = 0 {
        willSet {
            print("Nuovo valore: \(newValue)")
        }
        didSet {
            if totalePassi > oldValue {
                print("Aggiunti \(totalePassi - oldValue) passi")
            }
        }
    }
}

newValue e oldValue sono due costanti interne agli osservatori, che possiamo utilizzare all’interno dei blocchi di codice.

Ricorda se assegni una struttura a una var o passi un’istanza come parametro in una funzione, i valori verranno copiati. Le variabili sono quindi istanze separate del valore, ovvero se modifichiamo una, non cambierà nell’altra.