Для чего используется протокол Sequence (аналог Iterable) в Swift?

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

Ответ

Протокол Sequence предоставляет доступ к последовательному, возможно одноразовому, потоку значений. Это основа для итерации в Swift.

Ключевые области применения:

  1. Цикл for-in. Любой тип, conforming к Sequence, можно использовать в цикле.
    for number in 1...5 { // Диапазон — это Sequence
        print(number)
    }
  2. Функции высшего порядка и методы Sequence. Стандартные операции для обработки данных.
    let doubled = (1...3).map { $0 * 2 } // [2, 4, 6]
    let evens = (1...10).filter { $0 % 2 == 0 } // [2, 4, 6, 8, 10]
    let sum = (1...5).reduce(0, +) // 15
  3. Создание коллекций. Последовательность можно преобразовать в Array, Set, Dictionary.
    let setFromSequence = Set(1...5) // [5, 2, 3, 1, 4]
  4. Ленивые вычисления. Цепочка преобразований над lazy последовательностью применяется только по мере необходимости.
    let result = (1...1000).lazy
        .filter { $0 % 2 == 0 }
        .map { $0 * $0 }
        .first // Вычисляются только необходимые элементы
  5. Реализация пользовательских итераторов. Вы определяете логику перебора элементов.
    struct Countdown: Sequence {
        let start: Int
        func makeIterator() -> some IteratorProtocol {
            var count = start
            return AnyIterator { // Возвращает следующее значение или nil
                guard count > 0 else { return nil }
                defer { count -= 1 }
                return count
            }
        }
    }
    for num in Countdown(start: 3) { // 3, 2, 1
        print(num)
    }

    Важно: Sequence не гарантирует, что итерация по нему не будет иметь побочных эффектов или что ее можно повторить. Для многократного, безопасного доступа по индексу используется Collection.