Какие требования, кроме методов, могут содержать протоколы в Swift?

«Какие требования, кроме методов, могут содержать протоколы в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Протоколы в Swift могут определять разнообразные требования (requirements):

  1. Требования к свойствам: Указывается имя, тип и должны ли свойства быть доступны только для чтения ({ get }) или для чтения и записи ({ get set }).

    protocol Identifiable {
        var id: String { get }
        static var typeName: String { get }
    }
  2. Требования к методам: Могут быть экземплярными (func doWork()) и статическими (static func create()). Поддерживаются mutating методы и throws.

  3. Требования к инициализаторам:

    protocol Initializable {
        init(from decoder: Decoder) throws
    }
  4. Требования к сабскриптам:

    protocol ListRepresentable {
        subscript(index: Int) -> String { get set }
    }
  5. Ассоциированные типы (Associated Types): Позволяют создавать обобщенные (generic) протоколы. Тип указывается при реализации.

    protocol Container {
        associatedtype Element
        var items: [Element] { get }
        mutating func add(_ item: Element)
    }
  6. Опциональные требования: Доступны только для протоколов, помеченных @objc. Реализация таких требований не обязательна.

    @objc protocol OptionalProtocol {
        @objc optional func mightNotBeImplemented()
        var optionalProperty: String? { get @objc optional }
    }

Протокол определяет что должно быть реализовано, но не как. Соответствующий тип (класс, структура, перечисление) обязан предоставить конкретную реализацию всех неопциональных требований.