Closures are self-contained functions that can be used in different places in the code. We can also assign closures to variables. They're similar to lambda functions in other coding languages. Closures can be in a few different forms.
Global functions: They may be named or unnamed but do not capture any values.
Nested functions: They may be named or unnamed but capture values from their enclosing functions.
Closure expressions: They are unnamed and capture values from their surrounding context.
Closure expressions are the most widely used form of closure. They are unnamed functions that capture values from their surrounding context. We use closure expression to write in-line functions in a brief syntax. A closure expression may or may not return a value.
Closures have the following general syntax:
{ (parameters) -> returnType in// closure body}
We declare the arguments of the function in (parameters)
. Then we specify the return type, such as Int
or String
. After that, we insert the keyword in
, followed by the body of the function.
A simple example of this is a closure that takes a number as an argument and returns the next number. A closure can also be assigned to a variable, as shown below:
let addOne = { (number: Int) -> Int inreturn number + 1}let num = 3let afterClosureCall = addOne(num)print(afterClosureCall)
A closure can also be used as a function parameter. The following code example clarifies how it's used.
func performAction(number: Int, action: (Int) -> Int) -> Int {return action(number)}let num = 3let newNum = performAction(number: num, action: { (num: Int) -> Intinreturn num + 10})print("The first closure adds 10 and returns", newNum)//short-hand formlet anotherNum = performAction(number: num, action: { num in num * num })print("The second closure squares the number and returns", anotherNum)
Lines 1–3: We define a function performAction
that takes an Int
and closure as arguments. We also define the argument and return type of the closure.
Lines 6–10: We call performAction
with a closure that adds ten to num
and returns that number.
Line 13: We call performAction
again with an inline closure, but this time a short-hand form is used. Closures can be written this way as well, since they can infer the type and return implicitly.
A trailing closure is a closure expression that is written after the brackets of the function call. This is useful, especially in cases where the function call is long, to keep the code organized. There can be multiple trailing closures.
let n = 3let newN = performAction(number: n) { num innum * 2}print(newN)
Considering the performAction
function defined in the earlier example, a trailing closure can be called as shown in this example. Here, the closure expression doubles the number and returns it.
Autoclosures are closure expressions that are not enclosed in curly braces {}
. They can only contain a single expression. They do not take any arguments and return the value of that expression. The parameter type of a function that accepts an autoclosure has to be marked with the keyword @autoclosure
.
func callThrice(closure: @autoclosure () -> ()) {for _ in 1...3 {closure()}}callThrice(closure: print("Hello there!"))
Lines 1–5: We define a function callThrice
that takes an autoclosure
as an argument and calls it three times in a for
loop.
Line 7: We call the function callThrice
with the closure expression print("Hello there!")
Escaping closures are passed as function arguments after the function returns. One of the ways we can achieve this is by storing the closure in a variable defined outside the function.
var escapingClosures: [() -> Void] = []func functionWithClosure(closure: @escaping () -> Void) {escapingClosures.append(closure)}functionWithClosure(closure: {print("Hello there!")})escapingClosures[0]()
In the above example, the function is defined with the @escaping
keyword. The function containing the closure is called on line 6, but it does not print anything since the closure is escaping. The closure is later called separately on line 10, which prints "Hello there!" on the screen.
Free Resources