Что такое протоколы в Swift и почему Swift называют протокольно-ориентированным языком
Что проверяют
Понимаете ли вы, что протоколы с расширениями заменяют наследование, и знаете ли ограничения этого подхода.
Как отвечать
Протокол описывает требования: методы, свойства, связанные типы. Его реализует и класс, и структура, и перечисление, а один тип может соответствовать многим протоколам, тогда как наследоваться можно только от одного класса.
Протокольно-ориентированным язык называют потому, что поведение принято собирать из протоколов, а не наследовать. Ключевую роль играют расширения протоколов: они дают реализацию по умолчанию, поэтому протокол несёт не только контракт, но и поведение.
protocol Identifiable { var id: String { get } }
extension Identifiable { var shortId: String { String(id.prefix(8)) } }Что это даёт значимым типам: структура не может наследоваться, но может получить общее поведение через протокол с расширением. Так устроена вся стандартная библиотека, где Collection, Equatable, Comparable дают десятки методов бесплатно.
Дальше идут связанные типы (associatedtype) для обобщённых протоколов, ограничения расширений (where Element: Comparable), а с недавних версий some и any для разделения непрозрачных и экзистенциальных типов.
Важное ограничение: метод из расширения протокола, не объявленный в самом протоколе, вызывается статически по типу переменной, а не динамически. Это классический источник неожиданного поведения.
Где спотыкаются
Не знают про статическую диспетчеризацию методов расширения.
Считают протокол просто интерфейсом из Java, не упоминая расширений.
Путают some Protocol и any Protocol.
Делают протокол с десятью требованиями, из-за чего его реализуют через силу и с пустыми заглушками.