Swift,对不同的特定类型使用泛型 属性 - 对泛型类型的引用需要参数

Swift, use generic property with different specific types - Reference to generic type requires arguments in

如何分配 class 的实例,它可以具有通用类型,但直到 运行 时间你才知道它是什么类型?

例如。

我们有一个协议和符合它的枚举,如下所示:

protocol Stage: CaseIterable, Hashable {
    var fooBarLength: Int { get }
}

enum FirstStage: String, Stage {
    var fooBarLength: Int { 10 }
    case section1
    case section2
}

enum SecondStage: String, Stage {
    var fooBarLength: Int { 10 }
    case section1
    case section2
    case section3
}

接下来我们有某种控制器将协议用作通用类型...comme ça...

class FooBarController<StageType: Stage>: UIViewController {
    private var stages: [StageType: Float] = [:]
}

然后这样使用:

func fooBarScreen(boop: SomethingThatKnowsAboutTheStages) {
    var fooBarController: FooBarController // <---- how do I define this????

    if boop.someCondition() {
        fooBarController = FooBarController<FirstStage>()
    } else {
        fooBarController = FooBarController<SecondStage>()
    }
}

在 Java / Kotlin 中我可以像上面那样做,我如何在 Swift 中实现同样的事情?

目前我得到

"Reference to generic type 'FooBarController' requires arguments in <...>"

次要问题

是否有比必须在此处使用该 if 语句更通用的方法?理想情况下,我希望 fooBarScreen 方法不关心泛型类型,只让 SomethingThatKnowsAboutTheStages 为我提供类型。

您可以指定协议来提供 Stage 类型,如下所示:

protocol StageProvider {
    
    associatedtype T: Stage
    
    func getType() -> T.Type
    
}

然后让您的 SomethingThatKnowsAboutTheStages 或任何其他人遵守此协议:

class SomethingThatKnowsAboutTheStages: StageProvider {
    
    typealias T = SecondStage
    
    func getType() -> T.Type {
        SecondStage.self
    }
    
}

为您的 FooBarController 添加初始化程序:

class FooBarController<StageType: Stage>: UIViewController {
    
    convenience init(stage: StageType.Type) {
        self.init()
    }
    
}

最后使用所有这些:

func fooBarScreen<T: StageProvider>(boop: T) {
    let controller = FooBarController(stage: boop.getType())
}