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.
cannot invoke initializer for type 'Presenter' with an argument list of type ... expected an argument list of type '(dispatcher: Self.Dispatcher, view: Self.View)'
andcannot invoke 'attachView' with an argument list of type ... expected an argument list of type '(Presenter.View)'
– ParttimeCannot invoke initializer for type 'Presenter' with an argument list of type '(dispatcher: Presenter.Dispatcher!, view: AbstractListViewController<Presenter, Presenter.View.PDO>)'
, so basically some types are not resolved correctly for some reason. Maybe some constraints are not there. – InconstantPresenter.View == Self
, but that does not compile (obviously?). It says,Expected an argument list of type '(dispatcher: Self.Dispatcher, view: Self.View)'
– Inconstant