Ответ 1
Основная причина ограничения заключается в том, что Swift не имеет первоклассных метатипов. Самый простой пример - это не работает:
func isEmpty(xs: Array) -> Bool {
return xs.count == 0
}
В теории, этот код мог бы работать, и если бы это было сделано, было бы много других типов, которые я мог бы сделать (например, Functor и Monad, которые действительно не могут быть выражены в Swift сегодня). Но вы не можете. Вам нужно помочь Swift прибить это к конкретному типу. Часто мы делаем это с помощью дженериков:
func isEmpty<T>(xs: [T]) -> Bool {
return xs.count == 0
}
Обратите внимание, что T
здесь полностью избыточно. Нет причин, по которым я должен был бы это выразить; он никогда не использовался. Но Свифт требует его, чтобы он мог превратить абстрактный Array
в конкретный [T]
. То же самое верно и в вашем случае.
Это конкретный тип (ну, это абстрактный тип, который будет превращаться в конкретный тип при его создании и P
):
class ImplementProtocolA<P : ProtocolA>
Это полностью абстрактный тип, в котором Swift не имеет никакого правила превращаться в конкретный тип:
class ImplementProtocolB : ImplementProtocolA<ProtocolB>
Вам нужно сделать это конкретным. Это скомпилирует:
class ImplementProtocolB<T: ProtocolB> : ImplementProtocolA<T> {}
А также:
class UserDemoPresenter<T: GetUserView> : Presenter {
typealias V = T
}
Просто потому, что вы, вероятно, столкнетесь с проблемой позже: ваша жизнь будет намного проще, если вы создадите эти структуры или классы final
. Протоколы микширования, дженерики и полиморфизм классов полны очень острыми краями. Иногда вам повезло, и он просто не компилируется. Иногда он будет называть то, чего вы не ожидаете.
Возможно, вас заинтересует Маленький респект для AnySequence, в котором подробно описаны некоторые связанные с этим проблемы.
private var presenter : UserDemoPresenter<GetUserView>
Это еще абстрактный тип. Вы имеете в виду:
final class Something<T: GetUserView> {
private var presenter: UserDemoPresenter<T>
}
Если это создает проблему, вам нужно создать поле. См. Протокол не соответствует самому себе? для обсуждения того, как вы стираете тип, чтобы вы могли использовать абстрактные типы. Но вам нужно работать в конкретных типах. Вы не можете в конечном счете специализироваться на протоколе. В большинстве случаев вы должны специализироваться на чем-то конкретном.