In swift, closures are the self-contained blocks of code and that can be passed around in our code as function parameters. We can capture and store closure references in constants or variables based on our requirements.
In swift closure provide the ability to “close over” the variables and constants within the closure scope. Closures are basically designed for variables and constant means we assign the value in it and then passed it into function parameter.
Closures and functions are very similar. In swift functions are associated with names and but closures are not associated with a name that’s why it is called the lightweight champion.
If we want to access or retrieve the value of closure, we just assign a closure to the variable or constant and access all the values. In swift, closures are very popular compared to functions because closure has shorthand syntax which makes a lot easier when compared with function and we don’t need to declare just like a function.
Generally in swift functions are considered as a special cases of closures and closures can take any one of three form
In swift closures are enclosed in curly braces { } and followed by a function type () -> () and in keyword. Here -> separates the parameters & the return type and in keyword will separate the closure header from its body.
Following is the syntax of defining closures in a swift programming language.
{ (parameters) -> returntype in
//Statements
}
If you observe above closures syntax we defined parameters, return type and in keyword. In closures parameters and return types are optional.
Now we will see how to use closures in a swift programming language with examples.
Following is the example of showing different ways of using closures in a swift programming language.
// a closure without having any parameters and return types
var helloworld = {
print("Welcome to Tutlane")
}
helloworld()
//a closure with only return type
var addition = {() -> Int in
return100 + 500
}
print(addition())
//a closure with only parameter type
var onlyparam = {( x: String) in
print(x)
}
onlyparam("Welcome to Tutlane")
//a closure with single parameter and return type
var singleparam = {(x: String) -> String in
return x
}
print(singleparam("Welcome to Tutlane"))
//a closure with multiple parameters and return types
var multiplication = {(num1: Int, num2: Int) -> Int in
return num1 * num2
}
let result = multiplication (50, 100)
print(result)
If you observe above example we defined multiple closures with or without parameters and return types based on our requirements.
When we run the above program in swift playground we will get a result like as shown below
Welcome to Tutlane
600
Welcome to Tutlane
Welcome to Tutlane
5000
By using the swift sorted method 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 the same elements but in a particular order.
Following is the example of sorting array elements using closures in a swift programming language.
let names = ["Suresh", "Rohini", "Praveen", "Sateesh", "Madhav"]
var sortnames = names.sorted({ (s1: String, s2: String) -> Bool in
return s1 < s2
})
print(sortnames)
If you observe above example we are sorting elements in array using closures in swift.
When we run the above example in swift playground we will get result like as shown below
In swift, 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.
While running applications swift automatically judges the type of inference using input parameters in closures.
Following is the example of inferring type from closure context in swift programming language.
var multiplication = {(a: Int, b: Int) in
a * b
}
let result = multiplication (12,34)
print(result)
If you observe above example we defined closures without having any return type in swift programming language.
When we run the above example in swift playground we will get a result like as shown below
Single expression closures can return the result of their expression after omitting the return keyword from the declaration. Now here is the new version of writing a sorted closure.
Following is the example of using implicit returns in single expression closures in a swift programing language.
let names = ["Suresh", "Rohini", "Praveen", "Sateesh", "Madhav"]
var sortnames = names.sorted({ s1, s2 in s1 < s2 } )
print(sortnames)
If you observe above example we defined single expression in closure by omitting return type in declaration.
When we run above program in swift playground we will get a result like as shown below
This is how we can return the result of single expression closures with implicit returns in swift programming language.
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.
If we use shorthand argument names in closure expressions, we can omit closures arguments list from its definition.
Following is the example of using shorthand argument names in closure expressions to omit closures arguments from its definition.
let names = ["Suresh", "Rohini", "Praveen", "Sateesh", "Madhav"]
var sortnames = names.sorted({ $0 < $1 } )
print(sortnames)
If you observe above example we defined shorthand argument names in closures to omit usage of argument names in closures definition.
When we run the above program in swift playground we will get a result like as shown below
This is how we can shorthand argument names in closures to omit closures arguments list while declaring in swift programming language.
In swift closures can capture any variables and constants from their context which is defined in its surroundings. Closures can easily modify the values of constants and variables within its body.
In swift closure can remember the references of variables or constants from its context and use it whenever it called and the reference variables or constants will be destroyed only when the program stops execution.
Following is the example of capturing values using closures in swift programming language.
var num = 0
var incrementval = {
num += 1
}
var showval = {
print(num)
}
//It prints 0
showval()
//It increments 1
incrementval()
//It increments 2
incrementval()
//It prints 2
showval()
As we discussed closures can remember the references of variables or constants used it in context and use those values whenever it called. In above example num variable is in global context and that value will be destroyed only when program stops execution.
When we execute the above program in swift playground we will get a result like as shown below.
0
2
In swift the simple form of closure that can capture values is a nested function. The nested functions can capture the parameters of outer functions and access any of the variables and constants defined within the outer function.
Following is the example of capturing values in nested functions which defined inside the body of outer functions in a swift programming language.
func calculatevals (num1: Int) -> () -> Int {
var i = 0
func incrementval() -> Int {
i += num1
return i
}
return incrementval
}
let result = calculatevals(1)
print(result())
print(result())
print(result())
let result2 = calculatevals(100)
print(result2())
print(result2())
print(result2())
If you observe above example we are capturing parameter values and defined variables values from outside function “calculatevals” in nested function “incrementval”.
First time whenever we call closure “result” it will execute calculatevals() function and remember the value of variable “i” and use that update value next time whenever we call the closure and it will destroyed only when the program stops execution.
When we run the above program in swift playground we will get a result like as shown below.
1
2
3
100
200
300
This is how we can use closures to capture values in a swift programming language.
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.
Following is the example of using closures as reference types in a swift programming language.
//a closure with multiple parameters and return type
var multiplication = {(num1: Int, num2: Int) -> Int in
return num1 * num2
}
//Direct Accessing Closure
print(multiplication (50, 100))
//Assign closure to another variable
let result = multiplication
print(result(50, 100))
If you observe above example we defined closure & accessing it directly and referring same closure to other variable to perform operations.
When we run the above example in swift playground we will get a result like as shown below
5000
5000
This is how closures will act as reference types in swift programming language.
In swift if the last argument or parameter of a function become a closure then it is called as trailing closures.
When our closure expressions are longer than usual then it’s better to use trailing closures instead of longer closure expressions in swift.
Following is the example of using trailing closures as a last argument of the function in a swift programming language.
// Global Closure
func calculatevals(num: Int) -> Int { return num * 10 }
// Send Trailing Closure as a Parameter
func sum(num1: Int, num2: Int, closureparam: (Int) -> (Int)) -> Int {
var sum = 0
for i in num1...num2 {
sum += closureparam(i)
}
return sum
}
print(sum(0, 10, calculatevals))
If you observe above example we defined closure as a last parameter of the function in swift programming language.
When we run the above program in swift playground we will get a result like as shown below
This is how we can use trailing closures to replace long closure expressions in swift programming language.
In Swift functions if we pass closure as an argument and that closure called after the function returns then we can call it as closure is escaping from the function.
When we declare a function that takes a closure as an argument, we can write @escaping keyword before the parameter type to indicate that the closure is allowed to escape.
We have another way to escape closure by storing it in a variable that is defined outside of the function.
Following is the example of escaping closures in swift programming language.
var closurehandler: [( ) -> Void] = []
func escapeclosurefunction(closurehandler: @escaping () -> Void) {
closurehandler.append(closurehandler)
}
In the above escapeclosurefunction example, we are accepting closure function as an argument and add it to the closure which is declared outside of the function. In this function, if we didn’t mark a parameter as @escaping we will get a compilation error.
In swift autoclosure is a special closure that is automatically created to wrap an expression which is passed as an argument in a function. The autoclosure in swift does not take any arguments and whenever the autoclosure is called, it returns the value of an expression that is being wrapped inside of it.
In swift autoclosure will delay the code evaluation because the code inside the closure will not run until we call the closure.
Following is the example of using autoclosures in swift programming language.
func autoclosurefunction(checktwonumber: () -> Bool) {
if checktwonumber() {
print("It’s Correct")
}
else {
print("It’s Wrong")
}
}
autoclosurefunction({20 > 34})
If you observe above example we created closure without having any argument types.
When we run the above program in swift playground we will get a result like as shown below.
This is how we can use closures to maintain self-contained blocks of code to pass it as arguments for the functions in a swift programming language.