Что такое closure в Swift?

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

Ответ

Closure (замыкание) — это автономный блок функциональности, который может быть передан и использован в коде. Замыкания захватывают и хранят ссылки на переменные и константы из окружающего контекста.

Базовый синтаксис

let closureName: (ParameterTypes) -> ReturnType = { (parameters) -> ReturnType in
    // Тело замыкания
    return value
}

Примеры

Полная форма:

let multiply: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
    return a * b
}
print(multiply(5, 3)) // 15

Сокращённая форма (type inference):

let multiply = { (a: Int, b: Int) in a * b }
let sortedNames = names.sorted(by: { $0 > $1 })

Захват значений (capture list):

var counter = 0
let incrementer = { [counter] in // Захватываем текущее значение
    print(counter) // Всегда будет начальное значение
}
counter = 10
incrementer() // Выведет: 0

Особенности

  • Захват ссылок — по умолчанию замыкания захватывают сильные ссылки, что может вызвать retain cycles
  • @escaping — замыкание, которое вызывается после возврата из функции
  • @autoclosure — автоматически создаёт замыкание из выражения
  • Trailing closure — синтаксический сахар для последнего аргумента-замыкания

Использование

  1. Колбэки и completion handlers

    func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
       // Асинхронная операция
       completion(.success(data))
    }
  2. Функции высшего порядка

    let numbers = [1, 2, 3, 4]
    let doubled = numbers.map { $0 * 2 } // [2, 4, 6, 8]
    let evens = numbers.filter { $0 % 2 == 0 } // [2, 4]
  3. Кастомная сортировка и обработка данных