Swift Closures

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

 

  • Global Functions: These are treated as closures that have a name but it does not capture any value.
  • Nested Functions: These are also treated as closures that have name and it can captures values from the functions which are enclosed within the function.
  • Closure Expressions: These are the unnamed closures and written in lightweight context and that can capture values from their surrounding context.

Swift Closures Syntax

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.

Swift Closures 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

Swift Sort Elements in Closures

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

 

[Madhav, Praveen, Rohini, Sateesh, Suresh]

Swift Closures Inferring Type from Context

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

 

408

Swift Single-Expression Closures with Implicit Returns

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

 

[Madhav, Praveen, Rohini, Sateesh, Suresh]

This is how we can return the result of single expression closures with implicit returns in swift programming language.

Swift Shorthand Argument Names

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

 

[Madhav, Praveen, Rohini, Sateesh, Suresh]

This is how we can shorthand argument names in closures to omit closures arguments list while declaring in swift programming language.

Swift Closures to Capture Values

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.

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.

 

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. 

Swift Trailing Closures

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

 

550

This is how we can use trailing closures to replace long closure expressions in swift programming language.

Swift Escaping Closures

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.

Swift Autoclosures

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.

 

It's Wrong

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.