Result Builder — cos'è, sintassi e applicazione

Autore: IT Sectr Pubblicato: 2026-06-20 Tempo di lettura: 8 min

Result Builder è un attributo Swift implementato tramite il protocollo @resultBuilder che trasforma una sequenza di espressioni in un valore composto. Il compilatore converte blocchi di codice con costrutti di controllo if, for, switch in chiamate a metodi statici del builder — buildBlock, buildEither, buildArray. Secondo la proposta Swift Evolution SE-0289 (2022), i result builders consentono di creare DSL dichiarativi all'interno di Swift senza parser esterni. L'esempio più noto è @ViewBuilder in SwiftUI, dove il corpo della view è costruito da elementi condizionali e ciclici in uno stile dichiarativo.

Punti chiave

  • Result Builder — un attributo Swift che trasforma una sequenza di espressioni in un valore risultante tramite metodi statici del builder
  • @ViewBuilder — l'esempio più noto: trasforma più viste in un'unica rappresentazione composta TupleView
  • Costrutti di controllo — il builder supporta if/else, switch, for-in tramite i metodi buildOptional, buildEither, buildArray
  • Builder personalizzati possono essere creati per i propri DSL — HTML, CSS, configurazione, query
  • Swift 5.4 ha esteso il supporto dei result builders a funzioni e parametri di funzione — ora puoi applicare un builder a un argomento closure

Cos'è Result Builder?

Result Builder (precedentemente noto come function builders) è un meccanismo Swift che consente di trasformare una sequenza di espressioni separate da interruzioni di riga in un singolo valore. Viene dichiarato utilizzando l'attributo @resultBuilder applicato a una struttura che implementa metodi di trasformazione statici.

Prima dei result builders, la sintassi dichiarativa del body di SwiftUI era impossibile. Invece di un elenco compatto di viste, gli sviluppatori dovevano scrivere manualmente chiamate TupleView. Result Builder avvolge automaticamente ogni espressione, supporta ramificazioni e cicli, nascondendo allo sviluppatore la complessità della composizione.

Secondo Swift Evolution SE-0289, accettata nel 2022, il result builder è un'evoluzione dell'idea dei function builders (SE-0258, Swift 5.1). Modifiche principali: rinomina da @_functionBuilder a @resultBuilder ed estensione ai parametri di funzione, consentendo di utilizzare i builder per qualsiasi argomento closure, non solo per i corpi delle viste.

Utilizza i result builders quando devi fornire agli utenti della tua libreria una sintassi dichiarativa per costruire strutture complesse — configurazioni, query, componenti UI — senza scrivere codice assembly imperativo.

Come funziona Result Builder

Il compilatore Swift trasforma ogni blocco di codice contrassegnato con @resultBuilder in una sequenza di chiamate a metodi statici del builder. Diamo un'occhiata a un builder semplice che concatena stringhe:

swift
@resultBuilder
struct StringBuilder {
    static func buildBlock(_ parts: String...) -> String {
        parts.joined(separator: " ")
    }
}

Utilizzando questo builder — ogni stringa su una riga separata viene concatenata con uno spazio:

swift
@StringBuilder
func greeting() -> String {
    "Hello"
    "World"
    "from"
    "Swift"
}
// Il compilatore trasforma questo in:
// StringBuilder.buildBlock("Hello", "World", "from", "Swift")
// Risultato: "Hello World from Swift"

Il compilatore raggruppa le espressioni consecutive e le passa come parametri variadici a buildBlock. Se un if appare tra le espressioni, il compilatore chiama buildOptional o buildEither per la ramificazione. Per i cicli for-in, chiama buildArray. Così, il codice Swift normale viene trasformato in una catena di chiamate che costruiscono il valore finale.

Metodi del builder: buildBlock, buildOptional, buildEither

Ogni result builder definisce un insieme di metodi statici che il compilatore chiama durante la trasformazione. I metodi principali:

MetodoScopoQuando viene chiamato
buildBlockCombina una sequenza di espressioniPer ogni blocco senza ramificazione
buildOptionalGestisce if senza elseQuando c'è if senza else
buildEither(first:)Primo ramo di if-elsePer if con else
buildEither(second:)Secondo ramo di if-elsePer if con else
buildArrayGestisce i cicli for-inQuando for-in è presente
buildExpressionTrasforma espressioni individualiPer ogni espressione prima di passarla a buildBlock
buildFinalResultTrasformazione finalePrima di restituire dalla closure

Un'implementazione minima richiede solo buildBlock con parametri variadici — questo è sufficiente per blocchi senza ramificazione. Aggiungere buildOptional e buildEither include il supporto per costrutti condizionali, e buildArray per i cicli. Secondo la Documentazione Swift (2025), si consiglia di implementare tutti i metodi per la massima flessibilità del DSL.

buildExpression consente di accettare espressioni di diversi tipi e convertirle in un unico tipo di builder. Ad esempio, in @ViewBuilder, buildExpression accetta Text, Image, Button e li converte nel tipo comune View.

Creazione di un Result Builder personalizzato

Esaminiamo la creazione di un builder per costruire stringhe HTML. Questo DSL consentirà di scrivere HTML dichiarativo direttamente in Swift:

swift
@resultBuilder
enum HTMLBuilder {
    static func buildBlock(_ components: String...) -> String {
        components.joined()
    }

    static func buildOptional(_ component: String?) -> String {
        component ?? ""
    }

    static func buildEither(first component: String) -> String {
        component
    }

    static func buildEither(second component: String) -> String {
        component
    }

    static func buildArray(_ components: [String]) -> String {
        components.joined()
    }
}

Utilizzo del builder personalizzato per generare HTML:

swift
func div(@HTMLBuilder _ content: () -> String) -> String {
    "<div>\(content())</div>"
}

func p(_ text: String) -> String {
    "<p>\(text)</p>"
}

let page = div {
    p("Hello")
    p("World")

    if showFooter {
        p("Piè di pagina")
    }
}
// Risultato: <div><p>Hello</p><p>World</p><p>Footer</p></div>

Secondo l'articolo “Building Custom Result Builders in Swift” di Swift.org (2025), i builder personalizzati sono usati nelle librerie per costruire file di configurazione, componenti UI, mappatura dati e persino query di database — ovunque sia necessaria una sintassi dichiarativa con supporto di ramificazioni.

@ViewBuilder in SwiftUI

@ViewBuilder è un result builder integrato in SwiftUI che viene applicato al parametro content della maggior parte delle view contenitore: VStack, HStack, ZStack, Group, List e la proprietà body stessa. Consente di scrivere più viste su righe separate senza virgole o wrapper.

@ViewBuilder implementa tutti i metodi del result builder, inclusi il supporto per if-else, switch e for-in. Quando una condizione è vera, buildEither(first:) restituisce una vista; quando è falsa, buildEither(second:) ne restituisce un'altra. Entrambi i rami devono restituire lo stesso tipo, ma SwiftUI utilizza AnyView internamente o l'eliminazione del tipo tramite ConditionalContent.

swift
struct GreetingView: View {
    let isLoggedIn: Bool

    var body: some View {
        VStack {
            Image(systemName: "person.circle")
            Text("Profilo")
                .font(.title)

            if isLoggedIn {
                Text("Bentornato!")
                    .foregroundColor(.green)
            } else {
                Button("Accedi") { }
            }
        }
    }
}

Senza @ViewBuilder, lo stesso codice richiederebbe Group per ogni sezione condizionale o l'uso di AnyView, che penalizza le prestazioni. @ViewBuilder seleziona automaticamente la rappresentazione più efficiente — ConditionalContent o TupleView — per ogni combinazione.

Limitazioni di Result Builder

La prima limitazione è il numero massimo di espressioni in buildBlock. La libreria standard Swift definisce overload di buildBlock per 2–10 espressioni. Se un blocco ha più di 10 espressioni, il compilatore genererà un errore. La soluzione è raggruppare tramite Group o VStack per dividere in sottoblocchi.

La seconda limitazione è la mancanza di supporto per variabili e assegnazioni all'interno del blocco del builder. Non puoi dichiarare let x = 5 all'interno di @ViewBuilder. Tutte le espressioni devono essere espressioni che restituiscono un valore del tipo del builder. Per calcoli intermedi, usa calcoli al di fuori del builder o buildExpression con supporto per diversi tipi.

La terza limitazione è la complessità di debug. Gli errori di compilazione all'interno di un result builder spesso producono messaggi confusi, specialmente quando i tipi non corrispondono nei rami if/else. Usa tipi di ritorno espliciti e AnyView per il debug, sebbene quest'ultimo riduca le prestazioni. Secondo Hacking with Swift (2025), un consiglio pratico è iniziare con un builder semplice senza ramificazioni e aggiungere gradualmente il supporto per costrutti condizionali.

Domande frequenti

Cos'è Result Builder in Swift?

Result Builder è un attributo Swift che trasforma una sequenza di espressioni in un valore risultante tramite metodi statici. Consente di creare DSL dichiarativi, l'esempio più noto è @ViewBuilder in SwiftUI per costruire gerarchie di viste senza codice imperativo.

Come creare il proprio Result Builder?

Dichiara una struttura con l'attributo @resultBuilder e implementa almeno il metodo buildBlock. Per supportare condizioni, aggiungi buildOptional e buildEither; per i cicli, aggiungi buildArray. Usa l'attributo del builder prima del parametro closure in una funzione.

Quali metodi sono obbligatori per Result Builder?

Solo buildBlock è obbligatorio. Tutti gli altri metodi — buildOptional, buildEither, buildArray, buildExpression, buildFinalResult — sono opzionali e aggiungono supporto per i costrutti corrispondenti. Più metodi vengono implementati, più il DSL è flessibile.

Perché @ViewBuilder è un Result Builder?

@ViewBuilder è un'implementazione concreta del result builder per il protocollo View. È definito in SwiftUI come una struttura con l'attributo @resultBuilder, che fornisce metodi buildBlock per diversi numeri di viste (TupleView), buildEither per ConditionalContent e buildArray per ForEach.

C'è un limite al numero di espressioni in un builder?

, gli overload standard di buildBlock supportano fino a 10 espressioni. Superando questo limite, usa contenitori annidati (Group, VStack) per dividere in sottoblocchi. Un builder personalizzato può definire un buildBlock variadico senza limitazione.

Riepilogo

  • Result Builder — un attributo Swift che trasforma una sequenza di espressioni in un singolo valore tramite metodi statici del builder
  • Il compilatore sostituisce un blocco di codice con chiamate a buildBlock, buildEither, buildOptional, buildArray a seconda dei costrutti di controllo
  • @ViewBuilder — il result builder integrato di SwiftUI che consente di scrivere codice dichiarativo di gerarchia di viste con supporto per condizioni e cicli
  • Builder personalizzati vengono utilizzati per costruire DSL: HTML, configurazioni, query — qualsiasi struttura che benefici di una sintassi dichiarativa
  • Limitazioni: massimo 10 espressioni in buildBlock, impossibile dichiarare variabili, errori di compilazione confusi in caso di mancata corrispondenza dei tipi
  • Swift 5.4+ — i builder possono essere applicati ai parametri di funzione, ampliando i casi d'uso oltre i corpi delle viste

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