Custom result builders help you create a special way to build complex values step-by-step using simple code blocks.
Custom result builder declaration in Swift
@resultBuilder struct BuilderName { static func buildBlock(_ components: ComponentType...) -> ResultType { // Combine components into one result } // Optional: other static build methods like buildIf, buildEither, buildArray }
The @resultBuilder attribute marks a type as a result builder.
Inside, you define static methods to tell Swift how to combine parts.
@resultBuilder struct StringBuilder { static func buildBlock(_ components: String...) -> String { components.joined(separator: ", ") } }
@resultBuilder struct IntSumBuilder { static func buildBlock(_ components: Int...) -> Int { components.reduce(0, +) } }
This program defines a custom result builder called StringBuilder that joins strings with spaces. It also supports optional parts with buildIf. The makeSentence function uses this builder to create a sentence from code blocks.
import Foundation @resultBuilder struct StringBuilder { static func buildBlock(_ components: String...) -> String { components.joined(separator: " ") } static func buildIf(_ component: String?) -> String { component ?? "" } } func makeSentence(@StringBuilder content: () -> String) -> String { content() } let sentence = makeSentence { "Hello" if true { "world!" } } print(sentence)
Result builders let you write code that looks like normal blocks but creates complex results.
You can add methods like buildIf, buildEither, and buildArray to handle conditions and loops.
Use @resultBuilder before your builder struct to tell Swift it is a builder.
Custom result builders let you create special ways to combine code parts into one result.
They make your code cleaner and easier to read when building complex data.
Define static methods inside a @resultBuilder struct to control how parts combine.
Practice
@resultBuilder in Swift?Solution
Step 1: Understand the role of
A@resultBuilder@resultBuilderis used to customize how multiple code blocks combine into one result, making code cleaner.Step 2: Compare with other options
Options A, B, and D describe unrelated concepts like error handling, data types, and optimization, which are not the purpose of result builders.Final Answer:
To define how multiple code parts combine into a single result -> Option DQuick Check:
Result builder = combine code parts [OK]
- Confusing result builders with classes or structs
- Thinking result builders handle errors
- Assuming result builders optimize memory
Solution
Step 1: Identify correct syntax for result builder
A custom result builder must be declared with@resultBuilderattribute on a struct, and have static methods likebuildBlockreturning a value.Step 2: Check each option
@resultBuilder struct MyBuilder { static func buildBlock() -> String { "" } }correctly uses@resultBuilder, declares a struct, and has a staticbuildBlockmethod returning a String. The other options miss the attribute, use class instead of struct, or have non-staticbuildBlock.Final Answer:
@resultBuilder struct MyBuilder { static func buildBlock() -> String { "" } } -> Option AQuick Check:
Result builder = @resultBuilder + struct + static methods [OK]
- Using class instead of struct for result builder
- Forgetting the @resultBuilder attribute
- Making buildBlock non-static
@resultBuilder
struct IntSumBuilder {
static func buildBlock(_ numbers: Int...) -> Int {
numbers.reduce(0, +)
}
}
func sum(@IntSumBuilder _ content: () -> Int) -> Int {
content()
}
let result = sum {
5
10
3
}
print(result)Solution
Step 1: Understand buildBlock behavior
ThebuildBlockmethod takes multiple Int values and sums them usingreduce(0, +).Step 2: Evaluate the sum call
The closure passed tosumreturns three Int values: 5, 10, and 3. The builder sums them: 5 + 10 + 3 = 18.Final Answer:
18 -> Option BQuick Check:
Sum of 5, 10, 3 = 18 [OK]
- Thinking values concatenate as strings
- Expecting buildBlock to receive an array instead of variadic
- Confusing output with zero or error
@resultBuilder
struct TextBuilder {
func buildBlock(_ components: String...) -> String {
components.joined(separator: ", ")
}
}Solution
Step 1: Check method requirements in result builder
Methods likebuildBlockinside a@resultBuildermust be declared asstaticso they can be called without an instance.Step 2: Analyze the given code
ThebuildBlockmethod is missing thestatickeyword, which causes a compile error.Final Answer:
buildBlock must be static -> Option AQuick Check:
buildBlock method = static [OK]
- Omitting static keyword on buildBlock
- Thinking buildBlock must return Int always
- Believing struct can't be used with @resultBuilder
buildBlock implementations correctly combines multiple (String, Int) tuples into a single dictionary?Solution
Step 1: Understand the goal
The builder should combine multiple key-value pairs into a single dictionary.Step 2: Analyze each option
static func buildBlock(_ pairs: (String, Int)...) -> [String: Int] { Dictionary(uniqueKeysWithValues: pairs) } usesDictionary(uniqueKeysWithValues:)which correctly creates a dictionary from tuples. static func buildBlock(_ pairs: [(String, Int)]) -> [String: Int] { pairs.reduce([:]) { $0 + $1 } } tries to reduce with + which is invalid for dictionaries. static func buildBlock(_ pairs: (String, Int)...) -> [String: Int] { pairs.map { [$0.0: $0.1] } } maps to an array of dictionaries, not a single dictionary. static func buildBlock(_ pairs: (String, Int)...) -> [(String, Int)] { pairs } returns an array of tuples, not a dictionary.Final Answer:
static func buildBlock(_ pairs: (String, Int)...) -> [String: Int] { Dictionary(uniqueKeysWithValues: pairs) } -> Option CQuick Check:
Use Dictionary(uniqueKeysWithValues:) to combine tuples [OK]
- Returning array of dictionaries instead of one dictionary
- Using invalid + operator to combine dictionaries
- Returning array of tuples instead of dictionary
Ready to prove it?
Pass the test and this pattern moves unknown
