A closure is a kind of anonymous(no name) function that gets stored as a variable so it can be called later on, and has the special ability to remember the state of your program when you used it.Closures are typically enclosed in curly braces { } and are defined by a function type () -> (), where -> separates the arguments and the return type, followed by the ‘in’ keyword which separates the closure header from its body.Constants and variable references defined inside the functions are captured and stored in closures.
The general syntax for declaring closures is:
<pre>{ (parameters) -> return type in
statements
}</pre>
Closures can be defined in three ways:-
1. Global functions:- These are treated as a closures which have a name but it does not capture any value.
2. Nested functions:- These are also treated as a closures which have name and it can captures values from the functions which are enclosed within the function.
3. Closure expressions:- These are the unnamed closures and written in lightweight context and that can capture values from their surrounding context.
If the closure does not return any value you can omit the arrow (->) and the return type. This also applies to the case where the type of the closure can be infered.
<pre>{ (parameters) in
statements
}</pre>
Here the ‘in’ keyword is used to separate the return Type and statements inside the closure.The closure accepts parameters and can return value
Swift Closures Examples:-
Following is the example of showing different ways of using closures in swift programming language.
Closure without parameters and return types:-
<pre>var swiftClosure = {
print(“Welcome to swiftclosure😄”)
}
print(swiftClosure()) </pre>
Closure with only return type:-
<pre>var add = { () -> Int in
return 10 + 50
}
print(add()) </pre>
Closure with only parameter type:-
<pre>var parametersOnly = { (number:Int) in
print(number)
}
parametersOnly(5) </pre>
Closure with single parameter and return type:-
<pre>var singleparam = {(number:Int) -> Int in
return number
}
print(singleparam(4)) </pre>
Closure with multiple parameters and return types:-
<pre>var multiplication = {(number1:Int, number2:Int) -> Int in
return number1 * number2
}
let finalResult = multiplication(4, 5)
print(finalResult) </pre>
If we observe above example we defined multiple closures with or without parameters and return types based on our requirements.
When we run above program in swift playground we will get result like as shown below
<pre>Welcome to swiftclosure😄
60
5
4
20</pre>
Simplifying Closure Syntax
Sort Elements in Swift with Closures:-
With the help of sorted method in swift we can sort elements of arrays or lists in closures.The sorted method will sort array elements in ascending order and return it as a new array list with same elements but in particular order.
Example of sorting array elements using Swift closures.
<pre>let numbers = [3, 5, 2, 8, 0, 9, 7]
var sortNumber = numbers.sorted(by: {(number1: Int, number2: Int) -> Bool in
return number1 < number2
})
print(sortNumber)</pre>
When we run above example in swift playground we will get result like as shown below.
<pre>[0, 2, 3, 5, 7, 8, 9]</pre>
Inferring Type from Context in Swift Closure:-
we can use type inference to make more short syntax for the declaration of closure. For type inference we just remove the return type in closure.In closures after parameter declaration we can remove (->) sign and return type to create short form of using closures in swift.When we will run the application swift automatically judge the type of inference using input parameters in closures.
Example of inferring type from closure context in swift programming language
<pre>var addition = {(x: Int, y: Int) in
x + y
}
let addResult = addition(3,4)
print(addResult)</pre>
When we run above example in swift playground we will get result like as shown below.
<pre> 7</pre>
Swift Closures with Single-Expression and Implicit Returns:-
This is the new version of writing a sorted closure.
<pre>let empNames = [“Adarsha”, “Pankaj”, “Abhishek”, “Manoj”]
var sorted = empNames.sorted(by: { n1, n2 in n1 < n2})
print(sorted)</pre>
Single expression closures are returning the result of their expression after omitting the return keyword from declaration.
When we run above program in swift playground we will get result like as shown below.
<pre>[“Abhishek”, “Adarsha”, “Manoj”, “Pankaj”]</pre>
This is how we can return result of single expression closures with implicit returns in swift.
Using Shorthand syntax:-
Swift automatically provides a shorthand argument names to inline closures,which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.we are able to omit the parameter and return type along with the in and return keywords. By refering to each name of the array as $0, we are using Swift’s automatic parameter naming to shorten the amount of code we have to write.
<pre>let empNames = [“Adarsha”, “Pankaj”, “Abhishek”, “John”]
var sortNames = empNames.sorted(by: {$0 < $1})
print(sortNames)</pre>
When we run above program in swift playground we will get result like as shown below
<pre>[“Abhishek”, “Adarsha”, “John”, “Pankaj”]</pre>
This is how we can shorthand argument names in closures to omit closures arguments list while declaring in swift programming language.
Swift Closures As a Reference Types:-
In swift closures are the reference types that means if we assign one closure to more than one variable or constants then those variables or constants will refer to the same closure.
<pre>var addition = {(n1: Int, n2: Int) -> Int in
return n1 + n2
}</pre>
Direct Accessing Closure:-
<pre> print(addition(2, 3))</pre>
Assign closure to another variable:-
<pre>let result = addition
print(result(5, 10))</pre>
When we run above example in swift playground we will get result like as shown below
<pre>5
15</pre>
Trailing Closures:-
The Swift programming language defines a concept known as trailing closures. The idea is simple. If you pass a closure as the last argument of a function, you can place that closure outside the parentheses of the function call. The following example demonstrates how this works.
<pre>func trailingClosures(num:Int,onSuccess closure:(Int)->Void) {
closure(num * num * num)
}
trailingClosures(num: 10) { (numberCube) in
print(numberCube)
}</pre>
The argument label onSuccess is not there in the function call. Even though the closure is included in the function parameters list, swift will take it out of the parameter block to make the code more readable.
Completion Handlers:-
A completion handler is a type of Trailing Closure. It gets passed to a function as an argument and then called when that function is done.The point of a completion handler is to tell whatever is calling that function that it’s done and optionally to give it some data or an error. Sometimes they’re called callbacks since they call back to whatever called the function they’re in.
The use of Completion Handler is:
.To notify the user when the download completed
.Animation
We will create a closure which will be called within a function.
<pre>let completionHandlerBlock: (Bool) -> () = {
if $0 {
print(“Download Completed😎”)
}
}
let myCompletionHandlerBlock: (Bool) -> () = { (isSuccess: Bool) in
if isSuccess {
print(“Download has been finished😁”)
}
}</pre>
When we run above example in swift playground we will get result like as shown below
<pre>Download has been finished😁</pre>
.Here we will create a function that is similar to downloading file by calling a for-in loop. Once the download has been finished, we .may notify the user.
<pre>func downloadFile(completionBlock: (Bool) -> Void) {
for _ in 1…100{
print(“Downloading”)
}
completionBlock(true)
}</pre>
The function above takes a parameter whose type is (Bool) -> Void. We will pass myCompletionHandlerBlock.
<pre>downloadFile(completionBlock: myCompletionHandlerBlock)</pre>
When we run above example in swift playground we will get result like as shown below
<pre>Downloading
Downloading
Downloading
Downloading
.
.
.
Download has been finished😁</pre>
.We may pass a closure block directly when we execute the downloadFile function. Notice the trailing closure block.
<pre>downloadFile { (isSuccess: Bool) in
if isSuccess {
print(“Done, bruh🙂”)
}
}</pre>
When we run above example in swift playground we will get result like as shown below
<pre>Downloading
Downloading
Downloading
Downloading
.
.
.
Done, bruh🙂</pre>
Conclusion
Closures are an important concept, and we will use them often in Swift. Closures enable us to write flexible, dynamic code that is easy both to write and to understand.