Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Strutture

Alcuni esempi pratici (opportunamente analizzati) che mostrano come utilizzare le struct in Swift, analizzando le differenze con il linguaggio C e simili.
Alcuni esempi pratici (opportunamente analizzati) che mostrano come utilizzare le struct in Swift, analizzando le differenze con il linguaggio C e simili.
Link copiato negli appunti

Una struttura (o struct) permette di definire un nuovo tipo di dato composto a partire da proprietà e metodi.

Supponiamo di definire un nuovo tipo che vogliamo chiamare Indirizzo:

struct Indirizzo {
    let citta: String
    var numeroCivico: Int
    let via: String
    let cap: Int
}

In maniera simile alle classi, possiamo creare un'istanza di tipo Indirizzo usando la sintassi che già abbiamo visto per instanziare una classe:

let universitaDiCatania = Indirizzo(citta: "Catania",
                                    numeroCivico: 128,
                                    via: "Andrea Doria",
                                    cap: 90128)

Aggiungiamo adesso il metodo siTrovaIn, che ci permetta di stabilire se un indirizzo si trova nella città passata come argomento:

struct Indirizzo {
    let citta: String
    var numeroCivico: Int
    let via: String
    let cap: Int
    func siTrovaIn(citta: String) -> Bool {
        if self.citta == citta {
            return true
        } else {
            return false
        }
    }
}
universitaDiCatania.siTrovaIn("Catania")

A prima vista potremmo pensare che una struttura offra le stesse funzionalità di una classe. In parte è vero, ma con una fondamentale differenza: le strutture sono value type mentre le classi sono reference type. Questo significa che durante un'operazione di assegnamento viene copiato l'intero blocco di memoria occupato dalle proprietà dell'istanza, in una nuova area di memoria assegnata alla nuova variabile (o costante, o parametro). Nel caso di un reference type invece, la nuova variabile punta alla stessa area di memoria. Pertanto, nel caso di un value type (come una struct) le modifiche alle proprietà della nuova istanza (generata attraverso la copia con l'assegnamento) non avranno effetto sull'istanza originale.

Ad esempio:

var plessoDistaccatoUnict = universitaDiCatania
plessoDistaccatoUnict.numeroCivico = 142
print(universitaDiCatania.numeroCivico)      //  128

Se avessimo usato invece una classe per rappresentare il tipo Indirizzo, l' assegnazione precedente avrebbe fatto sì che il valore di numeroCivico fosse lo stesso per entrambe le variabili, dato che le classi sono reference type, ed entrambe le variabili avrebbero condiviso lo stesso blocco di memoria (di fatto puntando alla medesima istanza).

Una seconda differenza con le classi è che le strutture forniscono un inizializzatore di default, come visto nell'esempio precedente, che ha come parametri l'elenco delle proprietà della struttura.

È possibile definire più di un'inizializzatore. In questo caso però, quello di default non viene fornito automaticamente, e se è necessario, bisogna definirlo manualmente.

Continuando l'esempio precedente:

struct Indirizzo {
    let citta: String
    var numeroCivico: Int
    let via: String
    let cap: Int
    init() {
        self.citta = "NoWhere"
        self.numeroCivico = 0
        self.via = "Nessuna"
        self.cap = 0
    }
    init(citta: String, numeroCivico: Int, via: String, cap: Int) {
        self.citta = citta
        self.numeroCivico = numeroCivico
        self.via = via
        self.cap = cap
    }
    init(value: String) {
        var tokens = value.split(separator: ",")
        self.via = String(tokens[0])
        self.numeroCivico = Int(String(tokens[1]))!
        self.cap = Int(String(tokens[2]))!
        self.citta = String(tokens[3])
    }
}
var duomo = Indirizzo(value: "Piazza Duomo,1,95100,Catania")

Metodi mutanti delle strutture

A differenza del linguaggio C, è possibile definire dei metodi che interagiscono con le istanze delle strutture. Tuttavia, tali metodi non possono modificare il valore delle proprietà di default. È infatti necessario marcare esplicitamente questi metodi con la parola riservata mutating. Questo perché le strutture sono value type, cosa che, come abbiamo, visto implica la copia del blocco di memoria associato durante un'operazione di assegnazione. Un metodo che cambia una proprietà di un'istanza avrebbe dunque effetto solo su quella corrente e non sulle eventuali copie. Pertanto è necessario marcare esplicitamente un tale metodo, informando il compilatore Swift del fatto che lo sviluppatore è a conoscenza di tale comportamento.

struct Punto {
    var x = 0
    var y = 0
    mutating func muovi(x deltaX: Int, y deltaY: Int) {
        x += deltaX
        y += deltaY
    }
}
var unPunto = Punto(x: 10, y: 20)
unPunto.muovi(x: 2, y: 2)
print(unPunto). // Punto(x: 12, y: 22)

Ti consigliamo anche