0Pricing
Swift Academy · Lezione

Existential con any e type erasure

Utilizzare any Protocol, comprenderne il costo in termini di prestazioni e sapere quando preferire i generics.

Existential con any e type erasure è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 4 lezioni in totale.

Che cos'è un tipo esistenziale

Un tipo esistenziale inserisce in un contenitore qualsiasi valore conforme a un protocollo dietro un'interfaccia uniforme, risolvendolo in fase di esecuzione.

protocol Drawable { func draw() }
struct Line: Drawable { func draw() { print("Line") } }
let d: any Drawable = Line()
d.draw()

La parola chiave any

Swift 5.7 richiede la parola chiave any prima dei nomi dei protocolli usati come tipi esistenziali, per rendere esplicito l'inserimento nel contenitore.

func render(_ shape: any Drawable) {
  shape.draw()
}
render(Line())

Costo dei tipi esistenziali

I tipi esistenziali usano allocazione nell'heap e dispatch dinamico, che possono essere più lenti dei generics con dispatch statico.

// Existential – dynamic dispatch, potential heap alloc
var shapes: [any Drawable] = [Line(), Line()]
// Generic – static dispatch, no boxing
func drawGeneric<T: Drawable>(_ s: T) { s.draw() }

Il problema dei PAT e dei tipi esistenziali

I protocolli con tipi associati (PAT) non possono essere usati come esistenziali puri senza ricorrere al type erasure.

protocol Container { associatedtype Item }
// var c: any Container // Swift 5.7 allows with "any" but loses Item info

Pattern del type erasure

Un wrapper con type erasure incapsula un tipo concreto dietro una struct, nascondendo il tipo concreto.

struct AnyDrawable: Drawable {
  private let _draw: () -> Void
  init<D: Drawable>(_ d: D) { _draw = d.draw }
  func draw() { _draw() }
}

AnySequence e AnyPublisher

La stdlib di Swift e Combine includono wrapper con type erasure come AnySequence e AnyPublisher.

import Combine
let subject = PassthroughSubject<Int, Never>()
let pub: AnyPublisher<Int, Never> = subject.eraseToAnyPublisher()

eraseToAnyPublisher()

eraseToAnyPublisher() nasconde la catena concreta di publisher, così il codice chiamante dipende solo da AnyPublisher.

func fetch() -> AnyPublisher<String, Error> {
  URLSession.shared.dataTaskPublisher(for: URL(string: "https://example.com")!)
    .map { String(data: $0.data, encoding: .utf8) ?? "" }
    .eraseToAnyPublisher()
}

Quando usare gli esistenziali

Usi gli esistenziali per collezioni eterogenee o quando il tipo esatto non è noto al momento della compilazione.

var widgets: [any Drawable] = [] // mixed concrete types OK

Preferire i generics agli esistenziali

Quando possibile, sostituisca gli esistenziali con i generics per ottenere dispatch statico e prestazioni migliori.

// Prefer this:
func draw<T: Drawable>(_ item: T) { item.draw() }
// Over this:
func draw(_ item: any Drawable) { item.draw() }

Apertura degli esistenziali

Swift 5.7+ può "aprire" un esistenziale quando chiama una funzione generica, estraendo automaticamente il tipo sottostante.

func drawGeneric<T: Drawable>(_ d: T) { d.draw() }
let d: any Drawable = Line()
drawGeneric(d) // compiler opens the existential automatically

Type erasure e tipi opachi

Il type erasure nasconde il tipo per consentirne l'uso eterogeneo; i tipi opachi ne preservano l'identità per un unico tipo restituito coerente.

let erased: any Drawable = Line()   // runtime type unknown
let opaque: some Drawable = Line()   // compile-time fixed type

Verifica rapida

Qual è il principale costo in termini di prestazioni dei tipi esistenziali?

Riepilogo della lezione

Gli esistenziali (any Protocol) abilitano il polimorfismo a runtime al costo del dispatch dinamico. Il type erasure incapsula i tipi concreti dietro un'interfaccia stabile. Preferisca i generics per le prestazioni e usi gli esistenziali per le collezioni eterogenee.

Domande Frequenti

La lezione «Existential con any e type erasure» è gratuita?

Sì — il testo completo di «Existential con any e type erasure» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 4 lezioni in totale.

Cosa imparerò in «Existential con any e type erasure»?

Utilizzare any Protocol, comprenderne il costo in termini di prestazioni e sapere quando preferire i generics. Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Swift Academy?

Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Existential con any e type erasure»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Swift Academy?

Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Vincoli generici e clausole where
  2. Tipi opachi con la parola chiave some
  3. Existential con any e type erasure
  4. Associated type primari e typed throws
← Torna a Swift Academy