Chapters

Hide chapters

Swift Cookbook

Live Edition · Multiplatform · Swift · Editor agnostic

Pass Swift Closures as Arguments
Written by Team Kodeco

Closures in Swift are similar to blocks in C and Objective-C, and to lambdas in other programming languages. One of the key features of closures is that they can be passed as arguments to functions, just like any other type. This allows for powerful functional programming patterns, such as map, filter and reduce.

Here is an example of a simple function that takes a closure as an argument, which is used to perform an operation on an array of integers:

func operateOnArray(numbers: [Int], operation: (Int) -> Int) -> [Int] {
  // The operation closure is applied to each element of the array
  return numbers.map(operation)
}

In this example, the operateOnArray function takes two arguments: an array of integers and a closure of type (Int) -> Int. The closure is used to perform an operation on each element of the array, and the result is returned as a new array.

You can call this function and pass a closure as an argument like this:

let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = operateOnArray(numbers: numbers, operation: { (number) -> Int in
  return number * number
})
print(squaredNumbers)  // Output: [1, 4, 9, 16, 25]

In this example, you passed a closure that squares each number in the input array. The resulting array of squared numbers is printed out.

Shorthand Syntax for Closures as the Last Argument

It’s possible to use shorthand closure syntax when the closure is the last argument of the function call, allowing you to avoid typing the external variable name, and use a more readable syntax.

For example, a more shorthand way to write the previous example is this:

let squaredNumbers = operateOnArray(numbers: numbers) { (number) -> Int in
  return number * number
}

Shorthand Syntax with Type Inference

Thanks to Swift’s type inference, you can eliminate the closure’s parameter and return type, like this:

let squaredNumbers = operateOnArray(numbers: numbers) { number in
  return number * number
}

You could also use the shorthand syntax to refer to the closure argument by position rather than by name:

let squaredNumbers = operateOnArray(numbers: numbers) {
    return $0 * $0
}

However, it’s often nicer for readability to use the option where you refer by name rather than by position.

Passing closures as arguments to functions is a powerful feature of Swift that allows for concise and expressive functional programming. It’s a technique that can be used to simplify complex logic and make your code more readable and maintainable.

© 2024 Kodeco Inc.