Метод из расширения протокола: какая реализация вызовется
Вопрос
Метод bye() объявлен только в extension Greeter (не в самом протоколе), и структура Robot реализует свой bye(). Что вызовет let g: any Greeter = Robot(); g.bye()?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Реализацию
Robot: Swift всегда выбирает самую конкретную реализацию - Реализацию из расширения: метод не требование, вызов статическийправильный ответ
- Ошибку компиляции из-за неоднозначности двух реализаций
bye() - Случайную из двух, в зависимости от уровня оптимизации сборки
Разбор
Требования протокола попадают в witness table и вызываются динамически. Метод, объявленный только в расширении, не требование: компилятор выбирает реализацию по статическому типу. Для any Greeter это реализация расширения, для Robot реализация структуры. Чтобы вызывалась реализация типа, метод нужно объявить в самом протоколе. Неоднозначности и «случайности» нет, поведение детерминировано.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Протоколы, POP и дженерики»
- Протокол делегата и weak
- Протокол с associatedtype как тип параметра
- Как ускорить вызов методов класса
- Что такое associatedtype
- Виды диспетчеризации в Swift
- Type erasure в Swift
- Специализация дженериков
- Задача на Swift: k-й по величине в потоке через кучу