Closures in Swift
Closures in Swift
In this article, you’ll learn what is a closure, syntax, types of closures in Swift with examples.
Closures are mainly used for two reasons:
-
Completion blocks
Closures help you to be notified when some task has finished its execution. See Closure as a completion handler to learn more about it. -
Higher order functions
Closures can be passed as an input parameters for higher order functions. A higher order function is just a type of function that accepts function as an input and returns value of type function as output.
For this purpose it’s better to use closures in replacement of function because closure omits the func keyword and function name that makes the code more readable and short.
//As a variable:
var closureName: (ParameterTypes) -> ReturnType
//As an optional variable:
var closureName: ((ParameterTypes) -> ReturnType)?
//As a type alias:
typealias ClosureType = (ParameterTypes) -> ReturnType
//As a constant:
let closureName: ClosureType = { … }
How Do I Declare a Closure in Swift?
Let’s start with declaring alias for a closure which takes integer as argument and return integer.
In line 3, we are declaring a closure of type (Int)->Int using type alias declared above.
In line 5, we are defining the closure which will contain the logic.
In line 9 we are calling the closure with int as argument and output will be 25.
Notice the use of
in
keyword in
the closure definition. The
in
keyword is
used to separate the parameters and statements inside the
closure. The closure accepts parameters and can return value.
Lets learn to create your own closures with below examples:
Passing Closure as a function parameter and returning closure
In Swift, all closure parameters are no escaping by default. The concept of escaping and no escaping closure is for compiler optimization.
Escaping Closure
A closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns or the closure is used outside of the body of the function.
In the below example, test function takes argument of type aliasClosure and returns closure of type aliasClosure. Utilizing argument closure to calculate some value and pass that value in return closure. Output for line 11 will be 60.
Passing Closure as a function parameter , No return value
test2 function takes closure as argument but doesn't return any value. Output will be -20
Closure that contains statements but no arguments but return type exists
Below method takes closure as argument which doesn’t take any parameter but return int. Output will be print statement — “testStatement called” and print closure return value which is 1.
Trailing closure
If a function accepts a closure as its last parameter, the
closure can be passed similar to a function body between
{ }
. This type
of closure written outside of function call parentheses is known
as trailing closure.
AutoClosure
A closure which is marked with
@autoclosure
keyword is known as autoclosure.
@autoclosure
keyword creates an automatic closure around the expression by
adding a {}
.
Therefore, you can omit braces
{}
when passing
closures to a function.
The main advantage of using autoclosure is that you don’t need
to wrap the expression in curly braces
{}
when calling
closures.
Closure as a completion handler
Completion handler are callbacks/notifications that allows you to perform some action when a function completes its task.
Completion handler are mostly used in asynchronous operations so that the caller can know when the operation has completed to perform some action after the completion of the operation.
Higher order functions & Closures
Hope this article is useful for people which are trying to understand basics of closures, Please ❤️ to recommend this post to others 😊. Let me know your feedback. :)