Sobes.tech
Junior

Qual è la differenza tra strutture e classi in Swift?

sobes.tech AI

Risposta dell'AI

Differenze principali:

  • Tipo di valore vs. Tipo di riferimento: Le strutture sono tipi di valore, le classi sono tipi di riferimento. Assegnando una struttura o passando essa a una funzione, viene copio il valore. Assegnando una classe o passando essa a una funzione, viene copiata la referenza a un blocco di memoria.
  • Ereditarietà: Le strutture non supportano l'ereditarietà. Le classi supportano l'ereditarietà, consentendo di creare gerarchie di oggetti.
  • Deinitializers: Le strutture non hanno deinitializers. Le classi possono avere un deinit per liberare risorse.
  • Uguaglianza di identità: Per le strutture, viene confrontato il valore di tutte le loro proprietà (per impostazione predefinita usando ==). Per le classi, == confronta per impostazione predefinita le referenze (identità).
  • Prestazioni: Le strutture sono generalmente più performanti quando si lavora con piccoli volumi di dati, poiché non utilizzano allocazione dinamica sullo heap e non hanno costi aggiuntivi per il conteggio dei riferimenti (ARC).
Criterio Struttura (Struct) Classe (Class)
Tipo Valore (Value Type) Riferimento (Reference Type)
Ereditarietà No
Deinitializers No Sì (deinit)
Uguaglianza di identità Confronto per valore Confronto per riferimento
Posizionamento Di solito nello stack (per variabili locali) Sul heap
ARC No

La scelta tra struttura e classe dipende dalle esigenze. Le strutture sono adatte per modellare dati in cui è importante il passaggio per valore (ad esempio, coordinate, dimensioni). Le classi vengono utilizzate quando è richiesta l'ereditarietà, un riferimento mutabile condiviso a un oggetto o la gestione del ciclo di vita delle risorse.

// Esempio di struttura
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 0.0, y: 0.0)
var p2 = p1 // p2 è una copia di p1
p2.x = 5.0

// p1.x rimane 0.0
print("p1.x: \(p1.x), p2.x: \(p2.x)")

// Esempio di classe
class Circle {
    var radius: Double
    init(radius: Double) {
        self.radius = radius
    }
    deinit {
        print("L'istanza di Circle viene deallocata.")
    }
}

var c1 = Circle(radius: 1.0)
var c2 = c1 // c2 si riferisce alla stessa istanza di c1
c2.radius = 10.0

// c1.radius diventa anche 10.0
print("c1.radius: \(c1.radius), c2.radius: \(c2.radius)")

// Confronto di identità
if c1 === c2 { // Confronta le referenze
    print("c1 e c2 si riferiscono alla stessa istanza di Circle.")
} else {
    print("c1 e c2 non si riferiscono alla stessa istanza di Circle.")
}

// Confronto di valori (per le strutture)
let p3 = Point(x: 0.0, y: 0.0)
if p1 == p3 { // Confronta i valori di tutte le proprietà
    print("p1 e p3 hanno lo stesso valore.")
} else {
    print("p1 e p3 non hanno lo stesso valore.")
}