我正在定义一个具有某些功能和变量的协议
protocol BaseListPresenter {
associatedtype T
var values: [T] {get}
}
extension BaseListPresenter {
public func count() -> Int {
return values.count
}
public func valueAtIndex(index: Int) -> T? {
return values[index]
}
}
现在,我想在课堂上使用它:
class X: UIViewController {
var listPresenter: BaseListPresenter? // HERE it gives me error
// some other functions and variables here
}
上面说的错误:协议'BaseListPresenter'只能用作通用约束,因为它有Self或相关的类型要求
现在,我定义了X的子类:
class Y: X {
func setPresenter() {
self.listPresenter = UsersPresenter() // UsersPresenter confirms BaseListPresenter protocol with value's type "User"
}
// many more functions below
}
class Z: X {
func setPresenter() {
self.listPresenter = RoomsPresenter() // RoomsPresenter confirms BaseListPresenter protocol with value's type "Room"
}
// many more functions below
}
我已经通过创建UsersPresenter和RoomsPresenter从(Protocol can only be used as a generic constraint because it has Self or associatedType requirements)获得了解决方案。但是,我想创建BaseListPresenter类型变量,它将在X中采用不同类型的值(UIViewController);一次房间和下一次用户取决于X的子类。
如何解决此问题并按我的意愿使用?
答案 0 :(得分:0)
问题是,当协议在某处使用时,必须确定协议的关联类型。在您的课程X
的实施中,编制者不知道T
是什么类型。
我会这样实现:
class X<TPresenter : BaseListPresenter>: UIViewController {
var listPresenter: TPresenter? // HERE it gives me error
// some other functions and variables here
}
然后在派生时专门化X
:
class Y: X<UsersPresenter> {
func setPresenter() {
self.listPresenter = UsersPresenter() // UsersPresenter confirms BaseListPresenter protocol with value's type "User"
}
// many more functions below
}
class Z: X<RoomsPresenter> {
func setPresenter() {
self.listPresenter = RoomsPresenter() // RoomsPresenter confirms BaseListPresenter protocol with value's type "Room"
}
// many more functions below
}
这种结构有效。
注意:在UIViewController派生类中使用泛型会让我在一年前遇到麻烦。 Xcode /编译器无法将通用控制器与故事板中的场景链接起来。它不会导致编译错误,但在运行时也没有用 - 花费数小时的诊断时间。