Выбор ответа Middle Протоколы, POP и дженерики спрашивают часто обновлено

Метод из расширения протокола: какая реализация вызовется

Вопрос

Метод bye() объявлен только в extension Greeter (не в самом протоколе), и структура Robot реализует свой bye(). Что вызовет let g: any Greeter = Robot(); g.bye()?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Реализацию из расширения: метод не требование, вызов статический. Требования протокола попадают в witness table и вызываются динамически.

Варианты ответа

  1. Реализацию Robot: Swift всегда выбирает самую конкретную реализацию
  2. Реализацию из расширения: метод не требование, вызов статическийправильный ответ
  3. Ошибку компиляции из-за неоднозначности двух реализаций bye()
  4. Случайную из двух, в зависимости от уровня оптимизации сборки

Разбор

Требования протокола попадают в witness table и вызываются динамически. Метод, объявленный только в расширении, не требование: компилятор выбирает реализацию по статическому типу. Для any Greeter это реализация расширения, для Robot реализация структуры. Чтобы вызывалась реализация типа, метод нужно объявить в самом протоколе. Неоднозначности и «случайности» нет, поведение детерминировано.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.