Closure syntax

A general closure syntax is as follows:

 { (parameters) -> ReturnType in // body of closure }

A closure definition starts with {, then we define the closure type, and finally we use the in keyword to separate the closure definition from its implementation.

After the in keyword, we write the body of the closure and finish our closure by closing }.

Closures can be used to define variables or stored as variables. The following closure defines a variable of a type closure that accepts Int and returns Int:

let closureName: (Int) -> (Int) = { _ in 10 } 

Closures can be stored as optional variables. The following closure defines a variable of a type closure that accepts Int and returns Optional Int

var closureName: (Int) -> (Int)? 

Closures can be defined as typealiases. The following example presents typealias of a closure that has two Int parameters and returns Int.

typealias closureType = (Int, Int) -> (Int) 

The same typealias could be used for a function type definition as functions are named closures in Swift.

Closures can be used as an argument to a function call. For instance, the following example presents a function that is called with a closure that receives Int and returns Int:

func aFunc(closure: (Int) -> Int) -> Int  { 
// Statements, for example:
return closure(5)
}

let result = aFunc(closure: {
number in
// Statements, for example:
return number * 3
})

print(result) // prints 15

Closures can be used as function parameters. The following example shows an array sort method that receives a closure:

var anArray = [1, 2, 5, 3, 6, 4] 

anArray.sort(by: {
(param1: Int, param2: Int) -> Bool in
return param1 < param2
})

This syntax can be simplified with implied types as the Swift compiler has the ability to infer the types for parameters from the context as follows:

anArray.sort(by: { 
(param1, param2) -> Bool in
return param1 < param2
})

The syntax can be further simplified with implied return types using the Swift type inference:

anArray.sort(by: { 
(param1, param2) in
return param1 < param2
})

Swift enables us to eliminate the parameter name and open and close parentheses if we need to pass the closure as the last parameter of a function, in other words, if our closure is a trailing closure:

anArray.sort { 
(param1, param2) in
return param1 < param2
}

Also, Swift provides a shorthand argument notation that can be used instead of using arguments:

anArray.sort {  
return $0 < $1
}

We can simplify this syntax even further by eliminating the return keyword as we have only one line of expression, as follows:

anArray.sort { $0 < $1 } 

Using the Swift type inference, we were able to shorten the closure syntax drastically. Shorter syntax does not mean a simpler code to read and understand. It is recommended to find the optimum syntax that suits you and your team and adapt it consistently.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset