Core Concepts

Closures

Master Swift closures — self-contained blocks of functionality that capture their context.

What are Closures?

Closures are self-contained blocks of code that can be passed around and used in your code. They're similar to lambdas in other languages.

Swift closures can capture values from their surrounding scope.

Closure Syntax

Full syntax:

swift
{ (parameters) -> ReturnType in body }

Swift allows progressively simplified syntax for trailing closures.

Capturing Values

Closures capture references to the variables and constants from the surrounding context. This is powerful but requires care with [weak self] to avoid retain cycles.

Example

swift
// Full closure syntax
let add: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
    return a + b
}

// Simplified - infer types
let multiply: (Int, Int) -> Int = { a, b in a * b }

// Even shorter - shorthand argument names
let square: (Int) -> Int = { $0 * $0 }

print(add(5, 3))       // 8
print(multiply(4, 5))  // 20
print(square(7))       // 49

// Closures with higher-order functions
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

let evens = numbers.filter { $0 % 2 == 0 }
let doubled = numbers.map { $0 * 2 }
let sum = numbers.reduce(0) { $0 + $1 }  // or reduce(0, +)

// Trailing closure syntax
let sorted = numbers.sorted { $0 > $1 }  // descending

// Capturing values
func makeCounter(start: Int = 0) -> () -> Int {
    var count = start  // captured by the closure
    return {
        count += 1
        return count
    }
}

let counter = makeCounter(start: 10)
print(counter())  // 11
print(counter())  // 12
print(counter())  // 13

// Escaping closures (stored and called later)
var completionHandlers: [() -> Void] = []

func doSomething(completion: @escaping () -> Void) {
    completionHandlers.append(completion)
}

// Avoid retain cycles with [weak self]
class MyView {
    func loadData() {
        fetchData { [weak self] result in
            guard let self = self else { return }
            self.updateUI(with: result)
        }
    }
}
Try it yourself — SWIFT