Skip to content
Closures and Trailing Closure Syntax
step 1/6

Reading — step 1 of 6

Learn

~1 min readClosures and Generics

Closures in Swift are first-class values. The full form:

let square: (Int) -> Int = { (n: Int) -> Int in
    return n * n
}

Swift's type inference shrinks this aggressively. Each row below is the same closure:

let square: (Int) -> Int = { (n: Int) -> Int in return n * n }
let square: (Int) -> Int = { n -> Int in return n * n }
let square: (Int) -> Int = { n in return n * n }
let square: (Int) -> Int = { n in n * n }
let square: (Int) -> Int = { $0 * $0 }              // shorthand args

Trailing closure — when the last argument is a closure, you can move it outside the parens:

let doubled = [1, 2, 3].map({ $0 * 2 })
let doubled = [1, 2, 3].map { $0 * 2 }            // trailing

let sorted = [3, 1, 2].sorted { $0 > $1 }
let evens = [1, 2, 3, 4].filter { $0 % 2 == 0 }
let sum = [1, 2, 3].reduce(0) { acc, n in acc + n }

Multiple trailing closures (Swift 5.3+) for callbacks:

UIView.animate(withDuration: 0.3) {
    view.alpha = 0
} completion: { _ in
    view.removeFromSuperview()
}

Capturing self in a closure can create retain cycles. Use [weak self] in capture lists for callbacks owned by a long-lived object:

networkCall { [weak self] result in
    self?.handle(result)
}

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…

Closures and Trailing Closure Syntax — Swift Intermediate