Как определяется тип замыкания (closure) в Swift?

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

Ответ

Тип замыкания (closure) в Swift определяется сигнатурой его параметров и возвращаемого значения и записывается как (Параметры) -> ВозвращаемыйТип.

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

// 1. Без параметров, ничего не возвращает
let action: () -> Void = { print("Done!") }

// 2. Принимает Int, возвращает String
let transformer: (Int) -> String = { number in
    return "Value: (number)"
}

// 3. Принимает два String, возвращает Bool
let comparator: (String, String) -> Bool = { str1, str2 in
    return str1 == str2
}

Ключевые особенности типов замыканий:

  • @escaping: Помечает замыкание, которое может быть вызвано после возврата из функции (например, сохранено в свойство или передано в асинхронную задачу).
    var completionHandler: (() -> Void)?
    func doAsyncWork(completion: @escaping () -> Void) {
        completionHandler = completion // Захват для вызова позже
    }
  • @autoclosure: Автоматически оборачивает выражение в замыкание, откладывая его выполнение.
    func assert(_ condition: @autoclosure () -> Bool, _ message: String) {
        if !condition() { print(message) }
    }
    assert(2 * 2 == 5, "Math is broken") // Выражение вычисляется только внутри функции
  • Опциональные замыкания: Тип может быть опциональным.
    let optionalClosure: ((Int) -> Int)? = { $0 * 2 }
    let result = optionalClosure?(5) // result == 10