В чем разница между функцией и замыканием в Swift?

Ответ

В Swift функция — это частный случай замыкания. Замыкание — более общая концепция.

Функция: Именованное, самостоятельное замыкание, объявленное с помощью ключевого слова func.

// Именованная функция
func greet(name: String) -> String {
    return "Hello, (name)!"
}

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

// Замыкание (анонимная функция)
let greetClosure = { (name: String) -> String in
    return "Hello, (name)!"
}

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

  1. Захват контекста (Capture): Замыкание может захватывать и хранить ссылки на переменные из окружающей области видимости, даже если эта область уже прекратила существование.

    func makeIncrementer(incrementAmount: Int) -> () -> Int {
        var total = 0
        // Замыкание захватывает переменные `total` и `incrementAmount`
        let incrementer: () -> Int = {
            total += incrementAmount
            return total
        }
        return incrementer
    }
  2. Синтаксический сахар: Swift предоставляет упрощенный синтаксис для замыканий (trailing closures, shorthand argument names $0, $1).

    let numbers = [1, 2, 3]
    let doubled = numbers.map { $0 * 2 } // Trailing closure с shorthand argument
    // doubled = [2, 4, 6]

Итог: Все функции в Swift являются замыканиями, но не все замыкания являются именованными функциями. Замыкания — это фундаментальные строительные блоки для асинхронного кода, колбэков и функциональных преобразований (map, filter, reduce).

Ответ 18+ 🔞

Давай разберём эту дичь, но без заумного официоза, а как есть. Сидишь ты такой, пишешь на Swift, и тут бац — тебе говорят, что функция, это, типа, замыкание. А ты такой: «Чё, бля?». Ага, именно так, ёпта.

Смотри, представь себе замыкание как какого-то универсального солдата, который может быть кем угодно. А функция — это этот же солдат, но уже в парадной форме, с именной биркой и причёсанный. То есть, любая твоя func — это уже готовое, именованное замыкание. Оно просто прикинулось приличным.

Вот смотри, как это выглядит в коде, если не выёбываться:

// Это типа наш солдат в парадном мундире, с именем "greet"
func greet(name: String) -> String {
    return "Hello, (name)!"
}

А теперь тот же самый солдат, но в камуфляже, без имени — просто анонимный пацан с улицы:

// А это он же, но в трениках, его в переменную сунули
let greetClosure = { (name: String) -> String in
    return "Hello, (name)!"
}

По сути, одно и то же, но второе — более общая, дикая форма. И вся соль замыканий не в этом, а в двух вещах, от которых мозг может набекрень встать.

Первая фишка — захват контекста. Это вообще магия, ядрёна вошь. Замыкание может, как хитрая жопа, утащить с собой переменные из того места, где его родили, и хранить их у себя, даже когда родной дом уже давно снесён бульдозером.

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0 // Локальная переменная функции
    // А вот замыкание её ХВАТАЕТ и тащит с собой навсегда
    let incrementer: () -> Int = {
        total += incrementAmount // Оно помнит и total, и incrementAmount!
        return total
    }
    return incrementer // Функция кончилась, а замыкание с переменными живет дальше
}

Вот это и есть тот самый capture. Оно как бы замораживает кусок памяти и говорит: «Это моё, блядь, не тронь».

Вторая фишка — синтаксический сахар. Swift-разработчики, они же ленивые, как мартышлюшки, им писать (name: String) -> String in через раз лень. Поэтому они придумали сокращения, от которых глаза сначала вылазят, а потом привыкаешь.

let numbers = [1, 2, 3]
// Вместо длинной записи...
// let doubled = numbers.map { number in number * 2 }
// ...пишут так, используя эти долбаные $0, $1:
let doubled = numbers.map { $0 * 2 }
// doubled = [2, 4, 6]

Выглядит как какая-то тарабарщина, но через неделю ты уже сам будешь так писать, потому что реально быстрее. Trailing closure (когда замыкание пишут после скобок) и shorthand arguments ($0, $1) — это просто приколы языка, чтобы меньше пальцами шевелить.

Итог, чтобы не ебать тебе мозг окончательно: Все твои красивые func — это частный, именной случай замыканий. А замыкания — это и есть главные рабочие лошадки для всего асинхронного пиздеца, колбэков и этих вот функциональных штук: map, filter, reduce. Без них — никуда, придётся разбираться.