我正在尝试在我的应用程序中使用通用协议。我试图使用的代码是这样的。
protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
}
protocol PresenterProtocol {
associatedtype View
var view: View? { get set }
}
protocol ChildPresenter: PresenterProtocol where View == ChildProtocol {
}
protocol ChildProtocol: BaseProtocol where PresenterType == ChildPresenter {
}
class A: ChildProtocol {
var presenter: ChildPresenter?
}编译器在符合ChildProtocol时抛出错误
错误:协议'ChildPresenter‘只能用作泛型约束,因为它具有自或关联类型需求var presenter: ChildPresenter?
我不明白为什么编译器会抛出这个错误,而我已经清除了我的associateType。
发布于 2018-03-27 13:26:38
正如错误说的那样,ChildPresenter可以作为泛型使用,所以您必须将它放在类的声明中,例如。class A<T: ChildPresenter> : ChildProtocol
protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
}
protocol PresenterProtocol {
associatedtype View
var view: View? { get set }
}
protocol ChildPresenter: PresenterProtocol where View == ChildProtocol {
}
protocol ChildProtocol: BaseProtocol {
}
class A<T: ChildPresenter> : ChildProtocol {
var presenter: T?
func foo(bar: T) {
}
}您还可以使用ChildPresenter而不是T,如下所示
class A<ChildPresenter> : ChildProtocol {
var presenter: ChildPresenter?
}起初,这似乎限制了类A,因为在初始化之前必须指定ChilPresenter的类型,以后不能修改它,但这是必要的,因为ChildPresenter有关联的类型。
您可以看到,如果没有泛型,您可能会遇到麻烦,想象一下BaseProtocol还有一个属性
protocol BaseProtocol {
associatedtype PresenterType
var presenter: PresenterType? { get set }
var presented: PresenterType? { get set }
}presenter和presented都必须是相同的类型,因为您在这里说过

而class A也将拥有更多的财产:
class A<ChildPresenter> : ChildProtocol {
var presenter: ChildPresenter?
var presented: ChildPresenter?
}这样,您就可以保证presenter和presented都有相同的类型,因为在创建A对象时选择了该类型。let a = A<Foo>()

如果没有泛型,它就会像这样
class A: ChildProtocol {
var presenter: ChildPresenter?
var presented: ChildPresenter?
}这样,presenter可以是Foo型,presented可以是Bar型。所以你最终会有个悖论。这就是为什么您需要在A的声明中设置泛型类型。
https://stackoverflow.com/questions/49513649
复制相似问题