Introduction
Closures are self-contained blocks of functionality that can be passed around and used in your code, similar to functions. Unlike functions, closures can be written without a name and can capture and store references to constants and variables from the surrounding context in which they are defined. This capturing behavior is what makes closures powerful for callbacks, completion handlers, and functional-style operations.
Cricket analogy: A fielding coach's quick hand-signal instruction to the slip cordon is like a closure — it doesn't need a formal name, and it 'captures' the current field placement from the moment it's given, later used as a callback when the bowler actually delivers.
Syntax
{ (parameters) -> ReturnType in
statements
}
// Assigned to a constant
let multiply: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
return a * b
}Explanation
A closure expression has a parameter list, a return type, and a body, separated by the in keyword. Swift's syntax is progressively simplified in common cases: types can often be inferred from context so you can drop the parameter and return types; single-expression closures can omit the return keyword because Swift infers it automatically; and for very short closures you can use shorthand argument names $0, $1, and so on, instead of naming parameters. When a closure is the last argument to a function, Swift also lets you write it using trailing closure syntax, placing the closure body outside the parentheses.
Cricket analogy: Full field-instructions to a bowler would spell out (line, length) -> Outcome in, but experienced captains infer it from context, drop the formal wording, and just point using shorthand like 'there, there' ($0, $1) — and when it's the last instruction before the over, they say it trailing, after handing over the ball.
Example
let numbers = [5, 2, 8, 1]
// Full closure syntax
let sortedFull = numbers.sorted(by: { (a: Int, b: Int) -> Bool in
return a < b
})
// Trailing closure + type inference + implicit return
let sortedShort = numbers.sorted { a, b in a < b }
// Shorthand argument names
let sortedShorthand = numbers.sorted { $0 < $1 }
print(sortedFull)
print(sortedShorthand)Output
[1, 2, 5, 8]
[1, 2, 5, 8]Key Takeaways
- A closure has the form
{ (parameters) -> ReturnType in statements }. - Closures can capture and store references to variables and constants from their surrounding context.
- Swift allows progressively shorter syntax: type inference, implicit returns, and shorthand argument names like
$0. - Trailing closure syntax moves a final closure argument outside the parentheses.
- Closures are used extensively for callbacks and functional operations like
sorted(by:).
Practice what you learned
1. What keyword separates a closure's parameter/return list from its body?
2. What does it mean for a closure to 'capture' a variable?
3. What do `$0` and `$1` represent in a shorthand closure?
4. What is trailing closure syntax used for?
5. In `numbers.sorted { $0 < $1 }`, what syntax features are being used together?
Was this page helpful?
You May Also Like
Functions in Swift
Learn how to declare, call, and label the parameters of reusable blocks of code called functions in Swift.
Higher-Order Functions in Swift
Explore functions that take other functions or closures as arguments, such as map, filter, and reduce.
Escaping and Autoclosures in Swift
Learn what @escaping and @autoclosure mean, why closures are non-escaping by default, and when to use each attribute.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics