I was trying to understand the inner workings of _ConditionalContent but I wasn't able to implement a resultBuilder for it. This is how some of the resultBuilders for _ConditionalContent are defined:
static func buildEither<T: View, F: View>(first: T) -> _ConditionalContent<T, F>
This doesn't make sense to me because how is F determined? It can't be type erased to AnyView because I have seen both type parameters be concrete SwiftUI views, eg. _ConditionalContent<Text, Button>. It only makes sense that in conjunction with the other buildEither(second:) function is the final type for _ConditionalContent determined.
I wasn't able to get a rough-cut version of this working so if anyone can explain to me how to implement this using result builders please let me know:
struct ConditionalConent<T: View, F: View> {
let trueContent: T
let falseContent: F
}
@resultBuilder
struct ConditionalContentBuilder {
static func buildBlock<V: View>(_ content: V) -> V {
return content
}
static func buildEither<T: View, F: View>(first: T) -> ConditionalContent<T, F> {
// ... how is ConditionalContent created?
}
static func buildEither<T: View, F: View>(second: F) -> ConditionalContent<T, F> {
// ... how is ConditionalContent created?
}
}
Result builders were officially defined by SE-0289. The section Selection statements describes how
if/elsestatements are transformed. For your question, the answer is given by this sentence:Normally, in Swift, each statement is type-checked independently of other statements, so the statements inside the two branches of
if/elsecannot influnce each others' type-checking. But in anif/elsestatement inside a result builder, where both of the branches assign the result to the same (synthesized) variable, Swift uses both branches together to infer the type of that variable.This is similar to how both branches of a
?:operator must have the same type. For example, using your definition ofConditionalContent, we can write this:Swift can infer the types for
TandFby looking at both branches of the?:operator. A result builder performs a similar inference using both branches of anif/elsestatement.