Reading — step 1 of 4
Learn
~1 min readBuilders and Opaque Types
Result builders are how SwiftUI's view DSL works:
VStack {
Text("Hello")
Image("icon")
Button("Tap") { ... }
}
The block is processed by a result builder that combines each statement into a single result.
Defining a builder:
@resultBuilder
struct StringBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined(separator: " ")
}
}
@StringBuilder
func greeting() -> String {
"Hello,"
"world!"
"How are you?"
}
print(greeting()) // "Hello, world! How are you?"
The @StringBuilder annotation tells the compiler: pass each statement of the function body to buildBlock.
Optional and conditional support:
@resultBuilder
struct StringBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined(separator: " ")
}
static func buildOptional(_ component: String?) -> String {
component ?? ""
}
static func buildEither(first: String) -> String { first }
static func buildEither(second: String) -> String { second }
}
@StringBuilder
func message(formal: Bool) -> String {
"Greetings,"
if formal {
"esteemed friend."
} else {
"dude."
}
}
The builder's buildEither and buildOptional methods handle if / if-else and if let.
Result builder methods (implement only what you need):
buildBlock(_:)— required; merges statementsbuildOptional(_:)—if(no else)buildEither(first:),buildEither(second:)—if/elsebuildArray(_:)—forloopsbuildExpression(_:)— pre-process individual expressionsbuildFinalResult(_:)— final transform
Where used:
- SwiftUI views
- Server-side Vapor's
XCTAssert*builders - Plot HTML/CSS/JS builders
- Regex Builders (Swift 5.7+)
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…