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

问题描述 投票:0回答:2

如何分配一个可以具有泛型类型的类的实例,但在运行时之前你不知道它是什么类型?

例如。

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

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
为我提供类型。

swift generics enums protocols
2个回答
2
投票

您可以指定一个协议来提供

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())
}

0
投票

有帮助吗?这是我的代码:

class Person {
    public var attachValue: Any?
    func setAttachValue<T>(_ obj: T) {
        self.attachValue = obj
    }
    func getAttachValue<T>() -> T? {
        return attachValue as? T
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.