Protocol in Swift — cos’è, sintassi e possibilità

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

Protocol in Swift è un contratto che definisce un insieme di requisiti che qualsiasi tipo adottante deve soddisfare. I protocolli sono alla base della programmazione orientata ai protocolli (POP) — un paradigma raccomandato da Apple per Swift insieme alla classica OOP. Secondo la Apple Documentation, 2026, strutture, classi ed enum possono adottare protocolli, rendendo l’architettura flessibile e testabile.

Punti chiave

  • Protocol — un contratto con requisiti per strutture, classi ed enum
  • Requisiti includono metodi, proprietà, inizializzatori e subscript
  • Protocol Composition permette di combinare più protocolli
  • POP — programmazione orientata ai protocolli, alternativa all’ereditarietà
  • Protocol Extensions aggiungono implementazioni predefinite per i metodi

Cos’è un Protocol in Swift?

Protocol è un’interfaccia astratta che definisce ciò che un tipo deve essere in grado di fare, ma non come lo fa. In Swift, un protocollo è analogo alle interfacce in Java o Go, ma con capacità aggiuntive.

Un protocollo può richiedere:

  • Metodi di istanza e di tipo (statici)
  • Proprietà con specificatori { get } o { get set }
  • Inizializzatori
  • Subscript
  • Tipi associati (generici a livello di protocollo)

Secondo la WWDC 2015, Apple ha introdotto la programmazione orientata ai protocolli come approccio fondamentale per l’architettura delle applicazioni Swift. A differenza della OOP, dove l’ereditarietà delle classi crea gerarchie rigide, la POP offre la composizione di protocolli. Ciò offre flessibilità: un singolo tipo può conformarsi a più protocolli, ottenendo i loro requisiti e implementazioni tramite estensioni.

Sintassi di dichiarazione dei protocolli

Protocol viene dichiarato con la parola chiave protocol, un nome e un corpo.

swift
protocol Drawable {
    func draw(context: CGContext)
    var boundingBox: CGRect { get }
}

Un tipo adotta un protocollo usando due punti dopo il suo nome:

swift
struct Circle: Drawable {
    let center: CGPoint
    let radius: CGFloat

    func draw(context: CGContext) {
        context.addArc(center: center, radius: radius, ...)
    }

    var boundingBox: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
}

Un singolo tipo può adottare più protocolli separati da virgole: struct MyType: ProtocolA, ProtocolB. Il compilatore verifica che tutti i requisiti di ciascun protocollo siano soddisfatti.

Requisiti di proprietà e metodi

Requisiti di proprietà sono dichiarati con la parola chiave var e gli specificatori di accesso { get } o { get set }.

swift
protocol UserProtocol {
    var name: String { get }
    var age: Int { get set }
    static var maxAge: Int { get }
    mutating func updateName(_ newName: String)
}

La parola chiave mutating in un protocollo indica che il metodo può modificare self. Le strutture devono implementare tale metodo come mutating, mentre le classi possono ometterlo. Requisiti di metodi sono dichiarati con una firma completa, incluse le etichette dei parametri.

Ereditarietà dei protocolli

Protocol può ereditare un altro protocollo, aggiungendo nuovi requisiti. Ciò crea una gerarchia di contratti senza un accoppiamento rigido alle classi.

swift
protocol Vehicle {
    var speed: Double { get set }
    func move()
}

protocol Flyable: Vehicle {
    var altitude: Double { get set }
    func takeOff()
}

Un tipo che adotta Flyable deve soddisfare i requisiti di entrambi i protocolli — Vehicle e Flyable. Swift supporta l’ereditarietà multipla di protocolli: protocol A: B, C.

Protocol Composition

Protocol Composition è un meccanismo che permette di specificare che un tipo deve conformarsi a più protocolli simultaneamente, senza creare un nuovo protocollo combinato.

swift
func render(_ item: Drawable & Animatable) {
    item.draw(context: ...)
    item.animate(duration: 0.3)
}

La composizione (&) funziona nei parametri di funzioni, variabili e vincoli generici. Il compilatore verifica che il tipo passato simultaneamente soddisfi tutti i protocolli. La composizione è ampiamente utilizzata in SwiftUI: some View è un generico con composizione.

Protocol Composition è preferibile alla creazione di una gerarchia di ereditarietà: invece di protocol A: B, C, si può adottare direttamente B & C. Ciò offre flessibilità e riduce l’accoppiamento. La composizione è particolarmente utile nei parametri di funzioni e vincoli generici dove è necessario combinare temporaneamente requisiti senza creare un protocollo intermedio. Ciò riduce il numero di tipi ausiliari nel codice.

Protocollo come tipo

Protocol può essere usato come tipo di una variabile, parametro di funzione o elemento di collezione. Questo è chiamato tipo esistenziale.

swift
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]

func process(drawables: [any Drawable]) {
    for item in drawables {
        item.draw(context: ...)
    }
}

La parola chiave any (Swift 5.6+) marca esplicitamente un esistenziale. Senza any, il compilatore emette un avviso. Swift supporta anche some (tipi opachi) per nascondere il tipo concreto dietro un protocollo — questo è un approccio standard in SwiftUI.

Errori comuni con i protocolli

Quando si lavora con i protocolli, gli sviluppatori commettono spesso diversi errori ricorrenti.

  • Mutating dimenticato — un metodo è marcato come mutating nel protocollo, ma una struttura lo implementa senza la parola chiave
  • Protocollo come tipo invece di generico — usare Drawable invece di <T: Drawable> dove serve un tipo concreto
  • Riferimento circolare di protocollo — un protocollo che si riferisce a sé stesso attraverso un tipo associato senza risoluzione corretta
  • Protocollo solo per classi — usare AnyObject inutilmente, escludendo struct ed enum

Domande frequenti

In cosa differisce un protocol da una classe astratta?

Protocol definisce solo requisiti senza implementazione (fino ai protocol extensions). Una classe astratta può contenere implementazione e stato. Swift non ha classi astratte — il loro ruolo è svolto dai protocolli con estensioni.

Può una struct adottare un protocol?

, strutture, classi ed enum possono tutti adottare protocolli. Questa è la base della POP: non sei obbligato a usare classi per organizzare l’architettura. Le strutture con protocolli forniscono semantica di valore e immutabilità.

Cos’è un tipo associato in un protocollo?

Tipo associato (associatedtype) è un segnaposto per un tipo che il tipo implementante determina da sé. Esempio: Collection ha associatedtype Element. È un generico a livello di protocollo.

Posso limitare un protocollo solo alle classi?

, aggiungi l’ereditarietà da AnyObject: protocol MyProtocol: AnyObject. Allora solo le classi potranno adottare questo protocollo. È utile per riferimenti deboli e delegati.

Come verificare la conformità a un protocollo in runtime?

Usa is per verificare e as? per il casting: if let drawable = item as? Drawable. Funziona solo per protocolli senza tipi associati.

Riepilogo

  • Protocol — un contratto per metodi, proprietà, inizializzatori e subscript
  • Class, struct, enum — tutti i tipi possono adottare protocolli
  • Ereditarietà dei protocolli crea una gerarchia di contratti senza accoppiamento rigido
  • Protocol Composition (&) combina protocolli senza ereditarietà
  • Tipi esistenziali (any) e tipi opachi (some) — due modi per lavorare con i protocolli
  • POP è raccomandato da Apple come alternativa all’ereditarietà classica delle classi
  • Protocol Extensions permettono di aggiungere implementazioni predefinite

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