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…