struct — cos'è, concetti chiave e sintassi in Swift

Autore: IT Sectr Pubblicato: 2026-06-17 Tempo di lettura: 7 min

Struct è un tipo valore (value type) nel linguaggio Swift, le cui istanze vengono copiate quando passate tra parti di codice. A differenza delle classi, le strutture non supportano l'ereditarietà, ma implementano protocolli, contengono proprietà e metodi e forniscono una gestione della memoria prevedibile senza ARC. Secondo la Swift Programming Language Guide, 2026, struct è un elemento costitutivo fondamentale di Swift — anche i tipi standard Int, String, Array e Dictionary sono implementati come strutture. Il linguaggio raccomanda le strutture come scelta prioritaria per la modellazione dei dati.

Punti chiave

  • Struct è un tipo valore in Swift che viene copiato all'assegnazione e passato per valore, non per riferimento.
  • Copy-on-Write è un'ottimizzazione in cui la copia effettiva dei dati avviene solo quando il valore viene modificato, non all'assegnazione.
  • Mutating è la parola chiave richiesta per i metodi che modificano le proprietà di una struttura.
  • Protocolli — le strutture possono implementare protocolli ed estensioni, offrendo flessibilità senza ereditarietà.
  • Sicurezza — l'assenza di cicli di riferimento rende le strutture preferibili per codice multithread e modelli di dati.

Cos'è struct in Swift?

Struct (struttura) è un tipo di dato composito in Swift che raggruppa proprietà e metodi correlati in un'unica entità. A differenza delle classi, le strutture sono value types: quando vengono passate a una funzione o assegnate a una nuova variabile, viene creata una copia indipendente della struttura, non un riferimento all'oggetto originale.

Swift utilizza strutture per tutti i tipi primitivi: Int, Double, String, Bool, Array, Dictionary e Set. Ciò significa che anche un Int di base si comporta come una struttura — viene creata una copia all'assegnazione. Lo sviluppatore può definire la propria struttura con qualsiasi insieme di proprietà e metodi.

Secondo Swift Evolution (SE-0143), la decisione di implementare i tipi standard come strutture è motivata da prestazioni e prevedibilità. I value types non creano cicli di riferimento, non richiedono il conteggio dei riferimenti ARC e garantiscono che la modifica di una copia non influisca sull'originale — questo è criticamente importante per l'immutabilità dei dati in scenari multithread.

Struct come value type

La semantica dei value types è la differenza chiave tra struct e class. Quando si assegna una struttura a una nuova variabile o la si passa a una funzione, Swift crea una copia indipendente di tutti i dati. Qualsiasi modifica alla copia non influisce sull'originale, eliminando gli effetti collaterali tipici dei tipi riferimento.

swift
// Esempio di semantica value type
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 10, y: 20)
var p2 = p1        // p2 è una copia indipendente di p1
p2.x = 99            // Solo p2 cambia
print(p1.x)         // 10 — p1 invariato
print(p2.x)         // 99

Ottimizzazione Copy-on-Write

Swift utilizza Copy-on-Write (COW) per ottimizzare la copia. Se più variabili fanno riferimento alla stessa struttura ma nessuna modifica i dati, non avviene alcuna copia effettiva. Swift condivide la memoria tra le variabili fino alla prima mutazione — quindi viene creata una copia reale. Ciò previene operazioni di allocazione eccessive e accelera il lavoro con le collezioni.

Mutabilità e metodi mutating

Per impostazione predefinita, i metodi di una struttura non possono modificarne le proprietà — Swift richiede la parola chiave esplicita mutating per i metodi che apportano modifiche. Questa restrizione protegge dalla mutazione accidentale e rende il codice prevedibile: se un metodo non è marcato come mutating, è garantito che non modifichi la struttura.

Mutating in azione

Quando si aggiunge la parola chiave mutating prima di un metodo, Swift acquisisce la capacità di scrivere nuovi valori nelle proprietà della struttura. In effetti, il metodo può persino sostituire completamente l'istanza della struttura con una nuova tramite self =. Questo meccanismo viene utilizzato, ad esempio, nei tipi Option e Result.

swift
// Struct con metodo mutating
struct Counter {
    private var value: Int = 0

    // Metodo mutating — può modificare le proprietà
    mutating func increment() {
        value += 1
    }

    // Il metodo mutating può sostituire completamente self
    mutating func reset() {
        self = Counter()
    }

    // Metodo non mutating — sola lettura
    func currentValue() -> Int {
        return value
    }
}

var counter = Counter()
counter.increment()
print(counter.currentValue())  // 1
counter.reset()
print(counter.currentValue())  // 0

Regole per mutating: la struttura deve essere dichiarata con var, non con let — una struttura costante non può chiamare un metodo mutating. Il compilatore lo verifica al momento della compilazione: tentare di chiamare un metodo mutating su una costante let causerà un errore di compilazione.

Struct vs Class: confronto

La scelta tra struct e class è una delle decisioni fondamentali in Swift. Entrambi i tipi possono contenere proprietà, metodi, inizializzatori e implementare protocolli, ma presentano differenze fondamentali nella semantica della memoria, nell'ereditarietà e nella gestione del ciclo di vita.

Caratteristicastructclass
TipoValue type (copiato)Reference type (riferimento)
EreditarietàNon supportataSupportata
ARC / conteggio dei riferimentiNon richiestoARC richiesto
DeinizializzazioneNon supportataSupporta deinit
Modifica proprietà nelle costantiSolo tramite varPossibile tramite let (il riferimento è costante)
Type castingNon supportatoSupportato
Memorizzazione nelle collezioniMemorizzato direttamente (valore)Memorizzato come riferimento (puntatore)

Le strutture sono preferibili quando i dati non richiedono ereditarietà, non devono avere identità condivisa (ad esempio, coordinate, dimensioni, configurazione) e vengono passati tra moduli. Le classi vengono scelte per i componenti dell'interfaccia utente (UIView, UIViewController), singleton e oggetti con identità condivisa.

Quando scegliere struct

Apple raccomanda di utilizzare struct come tipo predefinito per la modellazione dei dati in Swift. Le strutture sono adatte alla maggior parte degli scenari grazie alla semantica di copia prevedibile e all'assenza di overhead del conteggio dei riferimenti. Esaminiamo i casi tipici in cui struct è la scelta ottimale.

Modelli di dati senza ereditarietà

Se un'entità contiene dati senza necessità di ereditarietà (Product, User, Order, Point), utilizza struct. Il compilatore genera automaticamente un memberwise initializer — non è necessario scrivere init manualmente. Equatable e Hashable vengono anch'essi implementati automaticamente per le strutture le cui proprietà sono tutte conformi a questi protocolli.

Dati immutabili

Per configurazioni, impostazioni e flag che non cambiano dopo la creazione, struct è preferibile a class. Una struttura costante (let) garantisce l'immutabilità di tutti i campi annidati — in una class questo si applica solo al riferimento, non al contenuto dell'oggetto.

Codice multithread

Le strutture sono sicure in ambienti multithread grazie alla semantica del valore. Ogni thread ottiene una copia indipendente dei dati e non influisce sugli altri thread. Le race condition tra thread sono impossibili per i value types, rendendo struct la scelta preferita per i modelli in SwiftUI (ObservableObject richiede class, ma @State utilizza struct).

swift
// Esempio di utilizzo di struct per modello dati
struct User: Codable, Identifiable {
    let id: UUID
    var name: String
    var email: String
    var isPremium: Bool

    // Proprietà calcolata — non mutating
    var displayName: String {
        isPremium ? "\(name) ⭐️" : name
    }
}

// Inizializzatore memberwise automatico
let user = User(
    id: UUID(),
    name: "Alice",
    email: "alice@example.com",
    isPremium: true
)

// La copia è sicura per il multithreading
var userCopy = user
userCopy.isPremium = false
// user.isPremium rimane true

Utilizza class quando hai bisogno di ereditarietà (componenti UIKit/AppKit), identità condivisa (delegate, observer) o ciclo di vita controllato dell'oggetto (deinit). Per tutto il resto — utilizza struct.

Domande frequenti

Cos'è struct in Swift?

Struct in Swift è un tipo valore che viene copiato quando passato tra parti di codice. Le strutture possono contenere proprietà, metodi, inizializzatori e implementare protocolli. I tipi di base di Swift (Int, String, Array) sono implementati come strutture.

Qual è la differenza tra struct e class in Swift?

Struct è un value type (copiato all'assegnazione), non supporta l'ereditarietà e non richiede ARC. Class è un reference type (passato per riferimento), supporta ereditarietà, deinizializzazione e conteggio dei riferimenti. Gli sviluppatori raccomandano struct come tipo predefinito.

Cos'è mutating in struct Swift?

Mutating è una parola chiave che indica che un metodo della struttura può modificarne le proprietà. Senza mutating, il compilatore vieta la modifica dei campi. I metodi mutating possono essere chiamati solo su variabili dichiarate con var, non con let.

Cos'è Copy-on-Write in Swift?

Copy-on-Write (COW) è un'ottimizzazione di Swift per le strutture in cui la copia effettiva dei dati viene differita fino alla prima mutazione. Finchè tutte le variabili leggono solo la struttura, condividono una singola area di memoria. Ciò migliora le prestazioni quando si lavora con grandi collezioni.

Quando usare struct e quando usare class in Swift?

Usa struct per modelli di dati senza ereditarietà, configurazioni, DTO e scenari multithread. Usa class per componenti UI UIKit/AppKit, singleton, entità con identità condivisa (delegate, observer) e oggetti che richiedono deinizializzazione.

Riepilogo

  • Struct è un tipo valore in Swift che viene copiato all'assegnazione, offrendo un comportamento prevedibile senza effetti collaterali tra le copie.
  • Copy-on-Write ottimizza le prestazioni delle strutture — la copia effettiva avviene solo alla prima mutazione, non a ogni assegnazione.
  • I tipi standard di Swift — Int, String, Array, Dictionary — sono implementati come strutture, garantendo semantica del valore per tutte le operazioni di base.
  • Mutating è una parola chiave obbligatoria per i metodi che modificano le proprietà della struttura; può essere chiamata solo su istanze var.
  • Le strutture non supportano l'ereditarietà ma implementano protocolli e possono utilizzare estensioni per aggiungere funzionalità.
  • Equatable e Hashable vengono implementati automaticamente per le strutture le cui proprietà sono tutte conformi a questi protocolli — semplificando il confronto e l'uso nelle collezioni.
  • Apple raccomanda struct come tipo predefinito — usa class solo quando sono necessari ereditarietà, identità condivisa o ciclo di vita controllato dell'oggetto.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche