Closures

A portrait painting style image of a pirate holding an iPhone.

by The Captain

on
May 17, 2023

Working with Swift Closures

Closures are self-contained blocks of functionality that can be passed around and used in Swift code. They are very similar to lambda functions in other programming languages. They can capture and store references to any constants and variables from the context in which they are defined. In this tutorial, we'll explore how to create and use simple closures in Swift.

Creating Closures

A closure expression has a similar syntax to a function. The only difference is that it does not require a function name. Here's a simple closure expression:

{ (parameters) -> return_type in
    statements
}

For example, let's create a closure that adds two integers:

let addClosure = { (a: Int, b: Int) -> Int in
    return a + b
}

We define a closure that takes two integer parameters, a and b, and returns an integer. It then adds the two parameters and returns the result. We can call this closure as we would a function:

let result = addClosure(1, 2) // result = 3

Passing Closures as Arguments

Closures can be passed as arguments to functions and methods. In this example, let's define a function that takes a closure as an argument and calls it:

func performOperation(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

The function performOperation takes two integer parameters, a and b, and a closure that takes two integers and returns an integer. It then calls the closure with the two integer parameters and returns the result. We can call this function with our addClosure:

let result = performOperation(a: 1, b: 2, operation: addClosure) // result = 3

We can also call this function with a closure expression:

let result = performOperation(a: 1, b: 2, operation: { (a: Int, b: Int) -> Int in
    return a * b
}) // result = 2

In this case, we defined a closure expression that multiplies the two integer parameters and passed it directly to performOperation as the operation argument.

Trailing Closure Syntax

If the last argument of a function is a closure, you can use trailing closure syntax to pass the closure expression outside of the function parentheses. This allows for cleaner, more concise code. Here's an example:

func performOperation(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let result = performOperation(a: 1, b: 2) { (a: Int, b: Int) -> Int in
    return a * b
} // result = 2

In this case, we call performOperation with the arguments a and b and then pass a closure expression that multiplies the two integer parameters using trailing closure syntax.

Conclusion

Closures are a powerful feature of the Swift programming language. They provide a way to encapsulate functionality that can be passed around and used in different contexts. In this tutorial, we explored how to create simple closures, pass them as arguments to functions, and use trailing closure syntax to create more concise code.