To complete this, learners should have knowledge of the following Swift concepts:
- Arithmetic Operators and Math in Swift
- Constants and variables
- Functions
| **Exercise Five Solution** | |
| `func commute(skating: (String) -> String) {` | |
| ` print("I'm heading out!")` | |
| ` let status = skating("Manhattan")` | |
| ` print(status)` | |
| ` print("I'm here!")` | |
| `} ` | |
| When you run this code in playground, you should get the following output - | |
| `I'm heading out!` | |
| `I'm skating to Manhattan on my board` | |
| `I'm here!` | |
| In this exercise we made a commute() function. It takes in one parameter, which is a closure that itself accepts one parameter and returns a string. That closure is then executed between two calls to print(). | |
| We can call commute() using code like this: | |
| `commute { (place: String) -> String in` | |
| ` return "I'm skating to \(place) on my board"` | |
| `}` | |
| But, Swift *knows* that our closure's parameter has to be a string, so we can get rid of it: | |
| `commute { place -> String in` | |
| ` return "I'm skating to \(place) on my board"` | |
| `}` | |
| Swift also knows our closure has to return a string, so we can remove that as well: | |
| `commute { place in` | |
| ` return "I'm skating to \(place) on my board"` | |
| `}` | |
| Since our closure only has one line of code, that line must also be the one that returns the value, so Swift lets us remove the return keyword too: | |
| `commute { place in` | |
| ` "I'm skating to \(place) on my board"` | |
| `}` | |
| Swift has a shorthand syntax that lets you write even shorter. Instead of writing `place in` we can let Swift provide automatic names for the closure’s parameters. These are named with a dollar sign, then a number counting from 0. | |
| `commute {` | |
| ` "I'm going to \($0) in my car"` | |
| `}` | |
| You did it! You learned closures in Swift! Pretty cool right? So let's review one more time... |
| **Exercise Four Solution** | |
| `let skatingReturn = { (place: String) -> String in` | |
| ` return "I'm skating to \(place) on my board"` | |
| `}` | |
| `let status = skatingReturn("Manhattan")` | |
| `print(status)` | |
| When we run the above code in playground, we get the following output − | |
| `I'm skating to Manhattan on my board` |
| Good job! Look below for the solution. | |
| **Exercise One Solution** | |
| `let Skating = {` | |
| ` print("I'm Skating to Tony's Pizzeria.")` | |
| `}` | |
| `Skating()` | |
| In this exercise you created a function without a name, and assigned that function to Skating. You can now call Skating() as if it were a regular function, like this: | |
| `Skating()` | |
| This is a simple example of how we can use closures. | |
| (See this link for more on [*Capturing Values*](https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID103)) |
| **Exercise Three Solution** | |
| `let Skating = { (place: String) in` | |
| ` print("I'm Skating to \(place) on my board")` | |
| `}` | |
| One of the differences between functions and closures is that you don’t use parameter labels when running closures. So, to call Skating() we’d write this: | |
| `Skating("Mcdonald's")` | |
| When we run the above code in playground, we get the following output − | |
| `I'm Skating to Mcdonald's on my board` | |
| Good job, let's move on to another way to use closures. |
| **Exercise Two Solution** | |
| `func player(name: String) -> String {` | |
| ` return name` | |
| `}` | |
| `print(player(name: "Player One Is..."))` | |
| `print(player(name: "Isaac!"))` | |
| `let playerTwo = {` | |
| ` print("Player two is... (your name)")` | |
| `}` | |
| `playerTwo()` | |
| When we run the above code in playground, we get the following output − | |
| `Player One Is...` | |
| `Isaac!` | |
| `Player two is... (your name)` | |
| In the above program, you defined a function and a simple closure. | |
| In Swift, you declare a function by using the “func” keyword. The function can take many parameters, from 0 onward. Every function has a name which tells you the task that function performs. Meanwhile, The type of the playerTwo closure is inferred to be of () -> () because it doesn't accept parameter and does not return a value. It will only print. | |
| So let's review... | |
| **Differences between Functions and Closures** | |
| * Closures are self-contained blocks of functionality, they can be passed around and used in our code. They look similar to blocks in Objective-C and C | |
| * Functions are declared using the func keyword where Closures don't have the func keyword in their declaration. | |
| * Functions always have a name but Closures do not | |
| * Functions don’t have the "in" keyword but closures have the "in" keyword | |
| * Functions use their values, while closures capture them | |
| Let's look at other ways to use Closures... |
In this lesson we will be learning about closures in Swift.
What are closures? Well, closures are very powerful features in Swift that allow you to capture functionality from one variable and store it somewhere else in your program. Imagine you manage an ice cream shop, and you're assigning tasks for the day to your employees. You say “here’s a job I want you to do later, but not right now.” Closures can be assigned work to be done later. Some examples of how closures are used include:
Closures let you encapsulate some functionality in a single variable, then store it somewhere else. We can also return it from a function, and store the closure somewhere else.
What does this mean? Essentially, you can create a function, then assign it to a variable, then call that function using that variable, and even pass that function into other functions as parameters. So functions that are used this way are called closures. They work just like functions do. But their syntax is written a little differently.
Closure expression syntax has the following general form.
{ (parameters) -> return type in
statements
}
In this syntax you define a closure which accepts parameters and returns a data type. Let's work on closures more in our first exercise!
Following is a simple exercise that builds upon basic closure syntax.
Instructions:
Good job! Look below for the solution.
Exercise One Solution
let Skating = {
print("I'm Skating to Tony's Pizzeria.")
}
Skating()
In this exercise you created a function without a name, and assigned that function to Skating. You can now call Skating() as if it were a regular function, like this:
Skating()
This is a simple example of how we can use closures.
(See this link for more on Capturing Values)
We learned about closures and how to declare them. But just what is the difference between a closure and a function?
Well, while a closure is a block of code that may capture variable values from its surrounding scope, a function is a statically defined block of code that may use variable values from its surrounding scope. Notice how these two are almost exactly the same thing, just at a conceptual level. The difference is that functions are traditionally invoked in the scope where they are defined, whereas closures are invoked — potentially — far away from their point of definition. Because of this, functions use, but closures capture, the relevant parts of their surrounding environment.
Let's create a closure and a function and see their differences.
Instructions
Good job! Look below for the solution.
Exercise Two Solution
func player(name: String) -> String {
return name
}
print(player(name: "Player One Is..."))
print(player(name: "Isaac!"))
let playerTwo = {
print("Player two is... (your name)")
}
playerTwo()
When we run the above code in playground, we get the following output −
Player One Is...
Isaac!
Player two is... (your name)
In the above program, you defined a function and a simple closure.
In Swift, you declare a function by using the “func” keyword. The function can take many parameters, from 0 onward. Every function has a name which tells you the task that function performs. Meanwhile, The type of the playerTwo closure is inferred to be of () -> () because it doesn't accept parameter and does not return a value. It will only print.
So let's review...
Differences between Functions and Closures
Let's look at other ways to use Closures...
When we create closures, we don’t give them a name or space to write any parameters. But that doesn’t mean they can’t accept parameters. Just that they do this in a different way: closure parameters are listed inside the open braces.
To make a closure take in parameters, list the parameters inside parentheses just after the opening brace, then write in so that Swift knows the main body of the closure is starting.
For example, we can create a closure that takes a place name string as its only parameter. Let's try it out!
Instructions
Good job! Look below for the solution.
Exercise Three Solution
let Skating = { (place: String) in
print("I'm Skating to \(place) on my board")
}
One of the differences between functions and closures is that you don’t use parameter labels when running closures. So, to call Skating() we’d write this:
Skating("Mcdonald's")
When we run the above code in playground, we get the following output −
I'm Skating to Mcdonald's on my board
Good job, let's move on to another way to use closures.
In our last exercise we used closures that accepted parameters. Closures can also return values, and they do this similarly to how they are written with parameters: you write them inside your closure, directly before the in keyword.
To show this, let's use our Skating() closure and make it return its value rather than print it directly. See the exercise below.
Here’s our original code:
let Skating = {
print("I'm Skating to Tony's Pizzeria.")
}
Skating()
Instructions
Good job! See the solution below.
Exercise Four Solution
let skatingReturn = { (place: String) -> String in
return "I'm skating to \(place) on my board"
}
let status = skatingReturn("Manhattan")
print(status)
When we run the above code in playground, we get the following output −
I'm skating to Manhattan on my board
Remember our second exercise, when we made a simple closure and its type could be inferred? Well, some closures can also implicitly return the result without needing a return keyword. These are known as single-expression closures.
Single-expression closures are closures that can implicitly return the result of their single expression by omitting the return keyword from their declaration. Let's work on another exercise to see this concept in action!
We declared a Skating closure in exercises 3 and 4. Let's use this closure again, only with a small change. Let's declare a function called commute and use the skating closure inside of it. Here's some starter code:
let Skating = {
print("I'm Skating to Tony's Pizzeria.")
}
Skating()
Instructions
Good job! Let's take a look at the solution.
Exercise Five Solution
func commute(skating: (String) -> String) {
print("I'm heading out!")
let status = skating("Manhattan")
print(status)
print("I'm here!")
}
When you run this code in playground, you should get the following output -
I'm heading out!
I'm skating to Manhattan on my board
I'm here!
In this exercise we made a commute() function. It takes in one parameter, which is a closure that itself accepts one parameter and returns a string. That closure is then executed between two calls to print().
We can call commute() using code like this:
commute { (place: String) -> String in
return "I'm skating to \(place) on my board"
}
But, Swift knows that our closure's parameter has to be a string, so we can get rid of it:
commute { place -> String in
return "I'm skating to \(place) on my board"
}
Swift also knows our closure has to return a string, so we can remove that as well:
commute { place in
return "I'm skating to \(place) on my board"
}
Since our closure only has one line of code, that line must also be the one that returns the value, so Swift lets us remove the return keyword too:
commute { place in
"I'm skating to \(place) on my board"
}
Swift has a shorthand syntax that lets you write even shorter. Instead of writing place in we can let Swift provide automatic names for the closure’s parameters. These are named with a dollar sign, then a number counting from 0.
commute {
"I'm going to \($0) in my car"
}
You did it! You learned closures in Swift! Pretty cool right? So let's review one more time...
let Skating = { (place: String) in
print("I'm Skating to \(place) on my board")
}
let skatingReturn = { (place: String) -> String in
return "I'm skating to \(place) on my board"
}
let status = skatingReturn("Manhattan")
print(status)
func commute(skating: (String) -> String) {
print("I'm heading out!")
let status = skating("Manhattan")
print(status)
print("I'm here!")
}
Final Review Solutions/Cheatsheet
Closures are functions that let you capture some functionality in a single variable, then store it somewhere else. We can also return it from a function, and store the closure somewhere else.
A closure allows you to capture and store variables outside its scope, unlike regularly written functions. They also allow you to..
Run your code after a pause or delay Running your code after an animation is done Running your code after a download is done Running your code when a user has chosen an option from your menu
{ (parameters) -> return type in
statements
}
let Skating = {
print("I'm Skating to Tony's Pizzeria.")
}
Skating()
Closures are self-contained blocks of functionality, they can be passed around and used in our code. They look similar to blocks in Objective-C and C Functions are declared using the func keyword where Closures don't have the func keyword in their declaration Functions always have a name but Closures do not Functions don’t have the "in" keyword but closures have the "in" keyword Functions use their values, while closures capture them
A closure can capture constants and variables from the surrounding context in which it is defined. The closure can then refer to and modify the values of those constants and variables from within its body, even if the original scope that defined the constants and variables no longer exists.
Are there bugs in this code (T/F)?: False
What's the output of this code?
I'm skating to Manhattan on my board
Are there bugs in this code? (T/F)?: False
Are closures outdated in Swift 5? (T/F) False
-Isaac Atif
I chose this topic because I was interested in writing about it. I like learning from solving programming problems, and writing about closures gave me an opportunity to share what I know, and also reinforce other areas. I used the Codecademy platform as a resource in designing this lesson. I also used Swift Developer documentation and stackoverflow. Coming up with problems can be tricky, but I like to learn from this process as it makes me feel more confident in my own skills.