Result Builder — un atribut Swift, implementat prin protocolul @resultBuilder, care transformа o secvenта de expresii иntr-o valoare compusа. Compilatorul transformа blocurile de cod cu construcтii de control if, for, switch иn apeluri ale metodelor statice ale builderului — buildBlock, buildEither, buildArray. Conform propunerii Swift Evolution SE-0289 (2022), result builderii permit crearea de DSL-uri declarative иn Swift fаrа analizatoare externe. Cel mai cunoscut exemplu — @ViewBuilder иn SwiftUI, unde corpul view-ului este construit din elemente condiтionale шi ciclice иn stil declarativ.
Principalele
TupleViewif/else, switch, for-in prin metodele buildOptional, buildEither, buildArrayResult Builder (cunoscut anterior ca function builders) — este un mecanism Swift care permite transformarea unei secvenтe de expresii separate prin linie nouа иntr-o singurа valoare. Este declarat cu atributul @resultBuilder aplicat unei structuri care implementeazа metode statice de transformare.
иnainte de apariтia result builderilor, sintaxa declarativа a SwiftUI body era imposibilа. иn locul unei liste compacte de view-uri, dezvoltatorul ar fi trebuit sа scrie manual apeluri TupleView. Result Builder иmbracа automat fiecare expresie, suportа ramificare шi bucle, ascunzаnd complexitatea compoziтiei de la dezvoltator.
Conform Swift Evolution SE-0289, adoptat иn 2022, result builder este o evoluтie a ideii function builders (SE-0258, Swift 5.1). Schimbаrile principale: redenumirea din @_functionBuilder иn @resultBuilder шi extinderea la parametrii de funcтii, ceea ce a permis utilizarea builderilor pentru orice argumente closure, nu doar pentru corpul view-ului.
Folosiтi result builderi cаnd doriтi sа oferiтi utilizatorilor bibliotecii dvs. o sintaxа declarativа pentru construirea structurilor complexe — configuraтii, interogаri, componente UI — fаrа a scrie cod imperativ de asamblare.
Compilatorul Swift transformа fiecare bloc de cod marcat cu @resultBuilder иntr-o secvenта de apeluri ale metodelor statice ale builderului. Sа considerаm cel mai simplu builder care concateneazа шiruri:
@resultBuilder
struct StringBuilder {
static func buildBlock(_ parts: String...) -> String {
parts.joined(separator: " ")
}
}
Utilizarea acestui builder — fiecare linie pe un rаnd separat este concatenatа printr-un spaтiu:
@StringBuilder
func greeting() -> String {
"Hello"
"World"
"from"
"Swift"
}
// Kompajler prevodi ovo u:
// StringBuilder.buildBlock("Hello","World","from","Swift")
// Rezultat: "Hello World from Swift"
Compilatorul grupeazа expresiile consecutive шi le transmite ca parametru variadic la buildBlock. Dacа иntre expresii apare if, compilatorul apeleazа buildOptional sau buildEither pentru ramificare. Pentru bucle for-in se apeleazа buildArray. Astfel, codul obiшnuit Swift este transformat иntr-un lanт de apeluri care construiesc valoarea finalа.
Fiecare result builder defineшte un set de metode statice pe care compilatorul le apeleazа иn timpul transformаrii. Metodele principale:
| Metodа | Scop | Cаnd este apelatа |
|---|---|---|
| buildBlock | Combinа o secvenта de expresii | Pentru fiecare bloc fаrа ramificare |
| buildOptional | Proceseazа if fаrа else | La prezenтa if fаrа else |
| buildEither(first:) | Prima ramurа a if-else | La if cu else |
| buildEither(second:) | A doua ramurа a if-else | La if cu else |
| buildArray | Proceseazа bucla for-in | La prezenтa for-in |
| buildExpression | Transformа o expresie individualа | Pentru fiecare expresie иnainte de a o trimite la buildBlock |
| buildFinalResult | Transformarea finalа | иnainte de returnarea din closure |
Implementarea minimа necesitа doar buildBlock cu parametri variadic — acest lucru este suficient pentru blocuri fаrа ramificare. Adаugarea buildOptional шi buildEither activeazа suportul pentru construcтii condiтionale, iar buildArray — pentru bucle. Conform Swift Documentation (2025), se recomandа implementarea tuturor metodelor pentru flexibilitate maximа a DSL-ului.
buildExpression permite primirea de expresii de diferite tipuri шi transformarea lor la tipul comun al builderului. De exemplu, иn @ViewBuilder, buildExpression primeшte Text, Image, Button шi le aduce la tipul comun View.
Sа considerаm crearea unui builder pentru construirea de шiruri HTML. Acest DSL va permite scrierea de HTML declarativ direct иn 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()
}
}
Utilizarea builderului personalizat pentru generarea HTML:
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("Podnožje")
}
}
// Rezultat: <div><p>Hello</p><p>World</p><p>Footer</p></div>
Conform articolului „Building Custom Result Builders in Swift” de pe Swift.org (2025), builderii personalizaтi sunt folosiтi иn biblioteci pentru construirea fiшierelor de configurare, componentelor UI, mapаrii datelor шi chiar a interogаrilor de baze de date — oriunde este nevoie de o sintaxа declarativа cu suport pentru ramificare.
@ViewBuilder — este un result builder иncorporat иn SwiftUI, aplicat parametrului content al majoritатii containerelor: VStack, HStack, ZStack, Group, List шi proprietатii body иn sine. Permite scrierea mai multor view-uri pe rаnduri separate fаrа virgule шi иmbrаcаminte.
@ViewBuilder implementeazа toate metodele result builder, inclusiv suportul pentru if-else, switch шi for-in. Cаnd condiтia este иndeplinitа, buildEither(first:) returneazа un view; cаnd nu — buildEither(second:) returneazа altul. Ambele ramuri trebuie sа returneze acelaшi tip, dar SwiftUI foloseшte AnyView intern sau шtergerea tipului prin ConditionalContent.
struct GreetingView: View {
let isLoggedIn: Bool
var body: some View {
VStack {
Image(systemName: "person.circle")
Text("Profil")
.font(.title)
if isLoggedIn {
Text("Dobro došli nazad!")
.foregroundColor(.green)
} else {
Button("Prijava") { }
}
}
}
}
Fаrа @ViewBuilder, acelaшi cod ar necesita Group pentru fiecare secтiune condiтionalа sau utilizarea AnyView, ceea ce degradeazа performanтa. @ViewBuilder alege automat cea mai eficientа reprezentare — ConditionalContent sau TupleView — pentru fiecare combinaтie.
Prima limitare — numаrul maxim de expresii иn buildBlock. Biblioteca standard Swift defineшte supraиncаrcаri ale buildBlock pentru 2–10 expresii. Dacа иn bloc sunt mai mult de 10 expresii, compilatorul va genera o eroare. Soluтia — grupare prin Group sau VStack pentru иmpаrтirea иn subblocuri.
A doua limitare — lipsa suportului pentru variabile шi atribuiri иn interiorul blocului builder. Nu se poate declara let x = 5 иn interiorul @ViewBuilder. Toate expresiile trebuie sа fie expresii care returneazа valoarea tipului builderului. Pentru calcule intermediare, folosiтi calcule иn afara builderului sau buildExpression cu suport pentru diferite tipuri.
A treia limitare — dificultatea de depanare. Erorile de compilare иn interiorul result builderului dau adesea mesaje confuze, mai ales la nepotrivirea tipurilor иn ramurile if/else. Folosiтi tipuri de returnare explicite шi AnyView pentru depanare, deшi ultimul reduce performanтa. Conform Hacking with Swift (2025), sfatul practic — иncepeтi cu un builder simplu fаrа ramificare шi adаugaтi suportul pentru construcтii condiтionale treptat.
иntrebаri frecvente
Result Builder — un atribut Swift care transformа o secvenта de expresii иntr-o valoare rezultat prin metode statice. Permite crearea de DSL-uri declarative, cel mai cunoscut exemplu fiind @ViewBuilder иn SwiftUI pentru construirea ierarhiei de view-uri fаrа cod imperativ.
Declaraтi o structurа cu atributul @resultBuilder шi implementaтi cel puтin metoda buildBlock. Pentru suportul condiтiilor, adаugaтi buildOptional шi buildEither, pentru bucle — buildArray. Folosiтi atributul builderului иnaintea parametrului closure din funcтie.
Doar buildBlock este obligatoriu. Toate celelalte metode — buildOptional, buildEither, buildArray, buildExpression, buildFinalResult — sunt opтionale шi adaugа suport pentru construcтiile corespunzаtoare. Cu cаt mai multe metode sunt implementate, cu atаt DSL-ul este mai flexibil.
@ViewBuilder — o implementare concretа a result builderului pentru protocolul View. Este definit иn SwiftUI ca o structurа cu atributul @resultBuilder, care oferа metodele buildBlock pentru diferite numere de view-uri (TupleView), buildEither pentru ConditionalContent шi buildArray pentru ForEach.
Da, supraиncаrcаrile standard ale buildBlock suportа pаnа la 10 expresii. La depашire, folosiтi containere imbricate (Group, VStack) pentru иmpаrтirea иn subblocuri. Un builder personalizat poate defini un buildBlock variadic fаrа limitare.
Concluzii
buildBlock, buildEither, buildOptional, buildArray иn funcтie de construcтiile de controlРазвићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође