Closures are self-contained lines of code to be executed and passed like any other data types. You should be familiar with blocks or at least heard about them in Objective-C or C. This recipe will help you to understand closure syntax and get familiar in using them.
Using closures to create self-contained code
Getting ready
Closures syntax in Swift is pretty easy and is easier than the syntax in C or Objective-C. The general form of closure is as follows:
{ (parameters) ->returnType in // block of code goes here }
As you see, you first put open curly braces, add list of parameters and the return type, then the keyword in, followed by lines of code in your closure. Closures are first-class type, which means it can be nested, passed in parameters, returned from function, and so on.
How to do it...
- Go to Xcode and create a new playground file called Closures to test code about closures in it.
- To see closures in action, copy and paste this piece of code in the playground file (the output of each statement is printed on the right):
var names = ["David", "Jones", "Suzan", "Naomi", "Adam"] names.sort() // ["Adam", "David", "Jones", "Naomi", "Suzan"] names.sort{ (str1: String, str2: String) ->Bool in return str1 > str2 } // ["Suzan", "Naomi", "Jones", "David", "Adam"]
How it works...
Swift provides us with a built-in system function called sort. The function can sort any collection of data. The function, by default, will sort the collection in an ascending order. The sort function gives us another flexibility by which you can provide a closure that returns the comparison result between any two items in the list to determine which should come first in the list.
As we saw, the default sort function sorts our data in an ascending order; in order to do any other logic, we can sort with closure that gives you two items as parameters to decide how to compare them. The sort function sorts the collection in place, and that's why the names variable is created as var not let. If the names collection is defined as let, you will not be able to use the sort() function. There is another function called sorted(), which returns a totally new sorted collection without changing the original one. It's available in both versions of the collection with var or let.
There's more...
Even though the closure syntax looks simple, but Swift can make it simpler. Let's see how closure syntax can be optimized.
Inferring type
When closures are passed as argument like what we did in the sort function, Swift can infer the types of closure parameters and return type. In that case, we can omit the parameters and return types, as there is no need to write them. In our previous example, when we infer types, the sort function would be like this:
names.sort{ str1, str2 in return str1 > str2 }
As you can see, the String types and the return type have been omitted.
Omitting the return keyword
Swift can make your life easier than that. When closure body consists of only one expression, the return keyword can be omitted. So, the new version of sort function will be like this:
names.sort({ str1, str2 in str1 > str2})
Shorthand arguments
To reach the maximum awesomeness of Swift, you can refer to the argument list with names $0, $1, and so on. When you decide to use the shorthand arguments, you can omit the list of parameters. You may ask what about the in keyword, will it be alone? The answer is no, we won't leave it alone; we can omit it as well completely. Here is the final version of our sort function:
names.sort({ $0 > $1})