Closures

A closure is a self-contained block of functionality. Functions, which you have been using already, are a special case of closures. You can think of a function as a named closure. Closures differ from functions in that they have a more compact and lightweight syntax. They allow you to write a function-like construct without having to give it a name and a full function declaration.

Define a closure to compare two Ints and check whether they are passed in in ascending order:

let compareAscending = { (i: Int, j: Int) -> Bool in
    return i < j
}

If you squint, closure syntax is similar to function syntax. You declare your parameters in parentheses, you declare your return type using the -> syntax, and you surround the functionality in curly braces.

There are a couple differences. The parameters and return type are declared within the curly braces, and there is an in keyword used to separate the closure signature from the closure implementation.

The closure you declared is assigned to the compareAscending constant. Use this variable to compare a few numbers:

let compareAscending = { (i: Int, j: Int) -> Bool in
    return i < j
}
compareAscending(42, 2)                                      false
compareAscending(-2, 12)                                     true

The closure is called just like a function, passing in the parameters in a list.

Closures’ concise syntax allows them to be easily passed around in function arguments and returns. For example, arrays have a sort(by:) method used to sort their contents. But the array does not know how you want to sort the contents: ascending order, descending order, or some other order. So sort(by:) takes in a closure that compares two of its elements. You determine whether those two elements are in the correct order, and then the array uses that knowledge to sort the entire array.

The compareAscending closure you defined fulfills exactly that responsibility; it compares two Ints and determines whether they were passed into the closure in ascending order. Define an array of numbers and use your compareAscending closure to sort it:

var numbers = [42, 9, 12, -17]                               [42, 9, 12, -17]

numbers.sort(by: compareAscending)                           [-17, 9, 12, 42]

Their lightweight syntax also allows closures to be passed inline to function calls. Sort the numbers array in descending order using an inline closure:

var numbers = [42, 9, 12, -17]                               [42, 9, 12, -17]

numbers.sort(by: compareAscending)                           [-17, 9, 12, 42]
numbers.sort(by: { (i, j) -> Bool in                         [-17, 9, 12, 42]
    return i < j                                             (6 times)
})

Since the numbers array contains Int elements, the types of i and j can be inferred. There are additional simplifications and shorthands to the closure syntax, and you will learn about many of those as you progress through this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.114.38