所以我试图理解通用协议和类:
protocol ListPresenterType where View.PDO.SW == Dispatcher.SW {
associatedtype Dispatcher: ListDispatcherType
associatedtype View: ListViewType
init(dispatcher: Dispatcher, state: @escaping (_ state: AppState)->(ListState<Dispatcher.SW>))
func attachView(_ view: View)
...
}
我从另一个泛型类启动它:
class AbstractListViewController<Presenter: ListPresenterType, PDO: ListPDOCommonType, ...>: ListViewType, ... where PDO.SW == Presenter.Dispatcher.SW, ... {
func configure(withBla: bla) {
...
presenter = Presenter(dispatcher: dispatcher, state: state)
}
func someFunc() {
presenter.attachView(self) // ERROR: Cannot invoke 'attachView' with an argument list of type ...
}
据我了解,我正在尝试初始化一个符合通用协议的类型,它工作得很好,但是 View 的类型必须与我试图输入的不一致attachView(:)
。
然后我尝试用具体的视图初始化它,改变init
:
init(dispatcher: Dispatcher, view: View, state: @escaping (_ state: AppState)->(ListState<Dispatcher.SW>)) {
self.view = view
...
}
并在AbstractListViewController
:
presenter = Presenter(dispatcher: dispatcher, view: self, state: state)
并得到这个臭名昭著的错误:
Non-nominal type 'Presenter' does not support explicit initialization
以下是相关游乐场的要点:
- 成功初始化(虽然不能调用
attachView(:)
)https://gist.github.com/nikans/0fde838846ffa9ff2da48c923f850625 - 初始化失败并出现上述错误:https ://gist.github.com/nikans/53c3ea146ceb12dc8461f7ba8a81793d
请注意,实际上每个空协议都有一个通用协议,我刚刚删除了不必要的细节。
我想了解:
- 是什么让“名义”类型突然变成“非名义”(没什么好奇怪的,它是符合通用协议的通用参数,但我不明白其中的因果关系)。
- 我听说过一些关于类型擦除的事情,但不太了解它是否适用于此。
谢谢。