Какие виды замыканий существуют в Swift?

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

Ответ

В Swift замыкания (closures) — это самодостаточные блоки функциональности, которые могут быть переданы и использованы в коде. Основные виды:

  1. Глобальные функции — именованные замыкания, которые не захватывают никакие значения из окружающего контекста.
  2. Вложенные функции (Nested functions) — именованные замыкания, определенные внутри другой функции, которые могут захватывать значения из внешней функции.
  3. Замыкающие выражения (Closure expressions)безымянные замыкания, записанные с использованием облегченного синтаксиса.

Примеры замыкающих выражений (от самого подробного к краткому):

// 1. Полная форма
let addFull = { (a: Int, b: Int) -> Int in
    return a + b
}

// 2. Неявный возврат (опускаем 'return' для однострочных замыканий)
let addImplicitReturn = { (a: Int, b: Int) -> Int in
    a + b
}

// 3. Сокращенные имена аргументов ($0, $1...)
let addShort: (Int, Int) -> Int = { $0 + $1 }

Специальные типы замыканий:

  • Убегающие замыкания (@escaping): Обозначают, что замыкание может быть вызвано после возврата из функции, в которую оно было передано (например, в асинхронных колбэках).
    func fetchData(completion: @escaping (Result<Data, Error>) -> Void) {
        URLSession.shared.dataTask { data, _, error in
            // Вызов completion происходит ПОСЛЕ завершения fetchData
            completion(.success(data!))
        }.resume()
    }
  • Автозамыкания (@autoclosure): Позволяют автоматически обернуть переданное выражение в замыкание, откладывая его вычисление до момента вызова.
    func assert(_ condition: @autoclosure () -> Bool, _ message: String) {
        if !condition() { // Вычисление происходит только здесь
            print(message)
        }
    }
    assert(2 * 2 == 5, "Математика сломалась") // Выражение 2*2==5 не вычисляется, если ассерты отключены.