So I'm trying to understand generic protocols and classes:
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)
...
}
And I'm initiating it from another generic class:
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 ...
}
As I understand, I'm trying to initialize a type conforming to a generic protocol, which works just fine, but the type of View must be inconsistent with what I'm trying to feed it in attachView(:)
.
Then I try to initialize it with concrete view, changing init
:
init(dispatcher: Dispatcher, view: View, state: @escaping (_ state: AppState)->(ListState<Dispatcher.SW>)) {
self.view = view
...
}
And in AbstractListViewController
:
presenter = Presenter(dispatcher: dispatcher, view: self, state: state)
And getting this infamous error:
Non-nominal type 'Presenter' does not support explicit initialization
Here're gists with relevant playgrounds:
- Successful init (though cannot invoke
attachView(:)
) https://gist.github.com/nikans/0fde838846ffa9ff2da48c923f850625 - Init failing with aforementioned error: https://gist.github.com/nikans/53c3ea146ceb12dc8461f7ba8a81793d
Please notice that every empty protocol there is in fact a generic protocol, I've just removed the unnecessary details.
I'd like to understand:
- What makes a "nominal" type "non-nominal" all of a sudden (nothing to be surprised of, it's a generic parameter conforming to a generic protocol, but I don't understand the causation).
- I heard something about type erasure, but didn't quite get if it is applicable here.
Thanks.
So it appears that in Xcode9 (beta 6) errors like
Non-nominal type '%type' does not support explicit initialization
simply equals themismatching types
error in less buggy Xcode (if that's a thing):cannot invoke initializer for type '%type' with an argument list of type '...' expected an argument list of type '...'