我试图了解_ConditionalContent的内部工作原理,但我无法为其实现一个ResultBuilder.以下是一些用于_ConditionalContent的ResultBuilder的定义:

static func buildEither<T: View, F: View>(first: T) -> _ConditionalContent<T, F>

这对我来说没有意义,因为F是如何确定的?它不能被类型擦除为AnyView,因为我已经看到两个类型参数都是具体的SwiftUI视图,例如._ConditionalContent<Text, Button>.唯一有意义的是,与其他buildEither(second:)函数一起是所确定的_ConditionalContent的最终类型.

我不能得到这个工作的粗略版本,所以如果有人能向我解释如何实现这using result builders,请让我知道:

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?
    }
}

推荐答案

结果构建者由SE-0289人正式定义.第Selection statements节描述了如何转换if/else条语句.对于你的问题,答案是这句话:

注意,所有到vMerged的赋值都将一起进行类型判断,这应该允许统一注入结果类型中的任何自由泛型参数.

通常,在SWIFT中,每条语句都独立于其他语句进行类型判断,因此if/else的两个分支中的语句不能相互影响对方的类型判断.但在结果生成器中的if/else语句中,两个分支将结果赋给相同的(合成的)变量,SWIFT同时使用这两个分支来推断该变量的类型.

这类似于?:运算符的两个分支必须具有相同的类型.例如,使用your definition of ConditionalContent,我们可以写成:

import SwiftUI

struct ConditionalContent<T: View, F: View> {
    var condition: Condition

    enum Condition {
        case isTrue(T)
        case isFalse(F)
    }
}

let vMerged: ConditionalContent = 1 > 2
    ? .init(condition: .isTrue(Text("really big one")))
    : .init(condition: .isFalse(Text("normal sized one").opacity(0.5)))

print(type(of: vMerged))
// output: ConditionalContent<Text, ModifiedContent<Text, _OpacityEffect>>

SWIFT可以通过查看?:操作员的两个分支来推断TF的类型.结果构建器使用if/else语句的两个分支执行类似的推理.

Swift相关问答推荐

UITableView未显示类数组数据

传递给SWIFT ResultBuilder的闭包中结果类型的对象

如何使用变量 Select 哪个向量(?)在我的 struct 中密谋吗?

为什么要在SWIFT RandomAccessCollection协议中重新定义元素类型?

';NSInternal不一致异常';,原因:';可见导航栏Xcode 15.0 Crash请求布局

Swift中从头开始的基本HTTP客户端

关闭 SwiftUI TabView 中的子视图

Swift数据关系

计算 CoreData 中所有唯一对象的数量?

如何从 RC 加载场景作为 ModelEntity 而不是普通实体?

如何在一个视图控制器中创建具有相同行为的多个集合视图?

为 SwiftUI 中的属性提供默认值

在主要参与者中启动分离任务和调用非隔离函数之间的区别

签署GoogleSignIn-GoogleSignIn需要开发团队

您可以在运行时访问 Picker 元素并更改它们的 colored颜色 吗

无法分配给属性:absoluteString是一个只能获取的属性

自定义 MKAnnotation 标注视图?

Swift if 语句 - 多个条件用逗号分隔?

如何快速格式化用户显示(社交网络等)的时间间隔?

将 [String] 存储在 NSUserDefaults 中