Day 6 : Closure

Another way to define a function

Jimmy Liu
Kuo’s Funhouse
Published in
4 min readOct 11, 2019

--

What is a Closure ?

In Swift, a Closure is basically a function that is defined as a variable. In Objective C, we called it a Block.

The general form of a closure looks like this :

Here is an example :

Closure that sums up two values

You can also create a closure without any input :

Or a closure that does not return any value :

Note : When writing a closure, if you didn’t state the type of the variable (ie : let printer: (String) →()), remember to use use () to define the type of the parameter inside the closure ( ie : {(str: String) in} ).

So what can we do with Closure ?

We can use it as Parameter and Return Type.

As Parameter

We can use it as parameters, such as the way map works :

map takes in a parameter called transform , which is a closure that takes in a generic type named Element and throws out another generic type named T .

Therefore, when we are using map, we can either fill in the closure :

Or we can define the closure in use it as a parameter :

As Return Type

Let’s make a function called finderGetter and an enum called FinderEnum. FinderEnum is used as a parameter when calling finderGetter. When finderGetter is called, it should return a function that shares the same structure as evenFinder from previous example.

As you can see, when returning the function, you can either return a closure by parameter or you can create a closure inside the function when returning.

Here is where things get a bit interesting. Below is a function called evenCounter. This function contains a counter variable and returns a closure. What is interesting is, we are going to change this counter variable inside the closure.

So what do you think will happen? Will the counter change or stays the same?

Let’s run the code and see what happened:

When the code runs, you can see the counter incremented whenever an even value is found :

So what does this mean?

This means that a closure can hold a copy or reference of variables outside of the closure, this could cause memory leakage if the variable is passed by reference. More on this later.

As Variables

You have already seen an example of closure as variable, remember evenFinder ?

Can we simplify a Closure body?

It depends. If you have only a line of code in the body, then you can, else , no.

Let’s keep using the previous example. I will show you the most completed style to the most shorthanded style.

Most completed :

With only a single line, we can get rid of the return

Since the closure knows the order of the parameters being used, we can use $0 to define the first parameter, $1 to define the second and so forth.

Also, because we can only return a value, no matter if it is a type, struct, class or tuple, therefore we can also omit → Bool in :

Summary

Closure is a function defined as variable.

You can use closure as parameter and as return value.

You can also hold a reference or copy of variables outside of the closure by calling the variable inside the closure. However, this might cause memory leakage, if the variable is passed by reference.

You can simplify a closure by replacing parameter names by $(_position of the parameter) ie : $0, $1 … If the closure contains only 1 line of code, you can even get rid of the return keyword.

--

--

Jimmy Liu
Kuo’s Funhouse

App Developer who enjoy learning from the ground up.