Closures are self-contained blocks of functionality that can be passed around and used in your code.
They are very similar to functions. In fact, global and nested functions in Swift are actually just special types of closures.
Closures are highly used in iOS development for completion handlers, sorting algorithms, and asynchronous network calls.
Closures are enclosed within curly braces {}.
They define parameters and a return type inside the braces, separated from the closure body by the in keyword.
let sayHello = { (name: String) -> String in
return "Hello, \(name)!"
}
print(sayHello("Akash"))
Because the closure is assigned to a variable (sayHello), we can call it just like a normal function.
One of the primary uses of closures is passing them as arguments to functions.
For example, the Swift array has a .sorted() method that takes a closure to determine how to sort the elements.
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]// Sorting alphabetically let sortedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 < s2 })
print(sortedNames)
Swift compiler is smart. It can infer the types of the parameters and the return type of the closure.
Furthermore, Swift provides shorthand argument names like $0, $1, $2 to refer to the closure's arguments.
This allows us to dramatically shrink the size of our closure code!
let names = ["Chris", "Alex", "Ewa", "Barry"]// Shrunk down using type inference and shorthand arguments let sortedNames = names.sorted(by: { $0 < $1 })
print(sortedNames)
If you need to pass a closure expression to a function as the final argument, you can use "trailing closure" syntax.
A trailing closure is written after the function call's parentheses, which makes the code much cleaner and easier to read.
let names = ["Chris", "Alex", "Ewa", "Barry"]// The closure is placed outside the parentheses! let sortedNames = names.sorted { $0 < $1 }
print(sortedNames)
What keyword is used inside a closure to separate the parameters/return type from the closure's body?