Ответ 1
Возможность наложения ограничений суперкласса на объявления протоколов (то есть возможность определять protocol P where Self: C
где C
- тип класса) была преждевременным следствием
SE-0156, и синтаксис должен был быть отклонен в Swift 4.x, пока функция не была реализована. Попытка использовать эту функцию в Swift 4.x может привести к неправильной компиляции и сбоям, поэтому я бы не использовал ее до Swift 5.
В Swift 5 (Xcode 10.2) эта функция теперь реализована. Из заметок о выпуске:
Протоколы теперь могут ограничивать свои соответствующие типы теми, которые подклассируют данный класс. Поддерживаются две эквивалентные формы:
protocol MyView: UIView { /*...*/ } protocol MyView where Self: UIView { /*...*/ }
Swift 4.2 принял вторую форму, но она не была полностью реализована и иногда могла вылетать во время компиляции или во время выполнения. (SR-5581) (38077232)
Этот синтаксис накладывает ограничение суперкласса на MyView
которое ограничивает соответствующие типы теми, которые наследуют (или являются) UIView
. Кроме того, использование MyView
семантически эквивалентно экзистенциальному классу (например, UIView & MyView
) в том UIView & MyView
что вы можете получить доступ как к членам класса, так и к требованиям протокола к значению.
Например, расширив пример заметок о выпуске:
protocol MyView : UIView {
var foo: Int { get }
}
class C : MyView {} // error: 'P' requires that 'C' inherit from 'UIView'
class CustomView : UIView, MyView {
var foo: Int = 0
}
// ...
let myView: MyView = CustomView(frame: .zero)
// We can access both 'UIView' members on a 'MyView' value
print(myView.backgroundColor as Any)
// ... and 'MyView' members as usual.
print(myView.foo)