Как выглядит синтаксис композиции протоколов в Swift?
Что проверяют
Знаете ли вы оператор & для протоколов и отличаете ли композицию от наследования протоколов. Следом обычно спрашивают, чем some P & Q отличается от any P & Q и можно ли расширить такую композицию через extension.
Как отвечать
Композиция записывается через амперсанд: Drivable & Flyable. Это не новый протокол, а требование «тип соответствует обоим сразу». Объявлять ничего не нужно: любой тип, который реализует оба протокола, подходит автоматически.
Где она встречается:
- параметр функции:
func start(_ v: some Drivable & Flyable)или в виде дженерикаfunc start<T: Drivable & Flyable>(_ v: T); - экзистенциал:
var vehicles: [any Drivable & Flyable], когда в одном массиве лежат разные конкретные типы; - псевдоним:
typealias FlyingCar = Drivable & Flyable. Так устроенCodableв стандартной библиотеке, этоDecodable & Encodable; - класс плюс протокол:
UIView & Configurableтребует наследникаUIView, который ещё и реализуетConfigurable. Класс в композиции может быть только один; AnyObject & SomeDelegate: ограничивает композицию ссылочными типами, это нужно дляweak-ссылок.
Затем объясните разницу с наследованием. protocol FlyingCar: Drivable, Flyable {} создаёт новый протокол, и тип начинает ему соответствовать только после явного объявления : FlyingCar, даже если оба метода у него уже есть. У композиции такого шага нет.
Про some и any: some фиксирует один конкретный тип на этапе компиляции, и компилятор может специализировать код. any упаковывает значение в экзистенциальный контейнер с динамической диспетчеризацией, это гибче, но дороже.
Где спотыкаются
Показывают наследование протоколов и называют его композицией. Интервьюер ждёт именно &.
Пытаются написать extension Drivable & Flyable. Композиция не номинальный тип, расширить её напрямую нельзя. Рабочий вариант: extension Drivable where Self: Flyable.
Не могут объяснить, зачем композиция нужна. Хороший пример: функции от аргумента нужны две маленькие возможности, и заводить ради этого третий протокол, на который придётся подписывать все типы, лишнее.