如何分配一个可以具有泛型类型的类的实例,但在运行时之前你不知道它是什么类型?
例如。
我们有一个协议和符合它的枚举,如下所示:
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())
}
有帮助吗?这是我的代码:
class Person {
public var attachValue: Any?
func setAttachValue<T>(_ obj: T) {
self.attachValue = obj
}
func getAttachValue<T>() -> T? {
return attachValue as? T
}
}