Как создать дженерик-протокол в Swift?

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

Ответ

Да, с помощью ассоциированных типов (associatedtype). Они определяют требования к типу, который будет указан при реализации протокола.

Базовый пример:

protocol Container {
    associatedtype Element
    var items: [Element] { get set }
    mutating func add(_ item: Element)
}

struct IntContainer: Container {
    // Явное указание типа (можно опустить, Swift выведет)
    typealias Element = Int
    var items: [Int] = []

    mutating func add(_ item: Int) {
        items.append(item)
    }
}

// Использование с автоматическим выводом типа
struct StringContainer: Container {
    var items: [String] = []
    mutating func add(_ item: String) { items.append(item) }
}

Протокол с ограничениями на тип:

protocol ComparableContainer {
    associatedtype Item: Comparable  // Ограничение
    func contains(_ item: Item) -> Bool
}

Ключевые отличия от дженерик-классов:

  • Протоколы используют associatedtype, классы/структуры — <T> в объявлении.
  • Ассоциированные типы более гибкие: конкретный тип определяется в реализации, а не при использовании протокола.
  • Это позволяет создавать коллекции разных типов, реализующих один протокол (например, [Container]), где каждый элемент может иметь свой Element.