Skip to content

Instantly share code, notes, and snippets.

@Isaaclipse
Last active August 5, 2021 17:14
Show Gist options
  • Select an option

  • Save Isaaclipse/f6bb8a5de75ba6137b5deb3bbc4ee55c to your computer and use it in GitHub Desktop.

Select an option

Save Isaaclipse/f6bb8a5de75ba6137b5deb3bbc4ee55c to your computer and use it in GitHub Desktop.
[iOS Development] Catalog Content Contributor Writing Submission by Isaac Atif

Prerequisites

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...

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:

    1. Running your code after a pause or delay
    1. Running your code after an animation is done
    1. Running your code when a user has selected an option from your menu
    1. Running your code when a download is done
    1. Running your code when a user has chosen an option from your menu

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.

1. Closure Expression Syntax

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!

Exercise One: Creating Simple Closures

Following is a simple exercise that builds upon basic closure syntax.

Instructions:

    1. Declare a constant called Skating as a function
    1. In the function body for Skating print a message that says "I'm Skating to Tony's Pizzeria."
    1. Call your Skating function

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)

Exercise Two: How Closures compare and contrast to Swift Functions

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

    1. Declare a function called Player
    1. Give your Player function a parameter value of name with type String and a return value of type String also. Then, in your function body, give the function a return value of name
    1. Print a message that calls your player function, along with the name value inside it, and type the message, "Player One Is..."
    1. Repeat step 3 on a new line, but instead type the message "Isaac!". Now, call your Player function
    1. On a new line create a simple closure called playerTwo. Reuse the same code from exercise one
    1. Print the message "Player two is... (your name)"
    1. Call your playerTwo closure

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

  • 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...

Exercise Three: Closures That Accept Parameters

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

  1. Declare a closure called Skating, and give it a parameter value of place with type String. Use the In keyword (see the closure syntax from the beginning of this lesson)
  2. print a message that says "I'm Skating to (place) on my board"
  3. Call your Skating closure and pass in a string value for place in your call

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.

Exercise Four: Closures That Return Values

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

    1. Using the starter code, declare a closure called "skatingReturn". Give it a parameter of place with type String and a return value of String.
    1. In your closure body return the string, "I'm skating to (place) on my board"
    1. We want our closure to return its string instead of printing it, so we need to use -> String before in, then use return just like a regular function:
    1. Declare a variable and give it a value of "skatingReturn." Now pass in a string for your place value.
    1. Run a print statement on your variable

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

Exercise Five: Single-Expression Closures

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

    1. Declare a function called commute. Give it a closure value of skating with parameter of String and return value of String.
    1. In your function body, print the string message "I'm heading out!"
    1. declare a constant and give it the name status. Give status a value of skating, and give skating a string parameter of your choice.
    1. Print status
    1. Print the message "I'm here!"
    1. Call your commute function

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...

Final Review

  1. What are closures?
  2. What do closures let you do in Swift?
  3. What is the basic Closure Expression Syntax?
  4. Following exercise one, how do you declare a closure that prints a message as output?
  5. How are closures different from functions?
  6. What does capturing values mean in relation to closures?
  7. Are there bugs in this code (T/F)?:

let Skating = { (place: String) in

print("I'm Skating to \(place) on my board")

}

  1. What's the output of this code?

let skatingReturn = { (place: String) -> String in

return "I'm skating to \(place) on my board"

}

let status = skatingReturn("Manhattan")

print(status)

  1. Are there bugs in this code? (T/F)?:

func commute(skating: (String) -> String) {

print("I'm heading out!")

let status = skating("Manhattan")

print(status)

print("I'm here!")

}

  1. Are closures outdated in Swift 5? (T/F)

Final Review Solutions/Cheatsheet

  1. 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.

  2. 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()

  1. 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

  2. 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.

  3. Are there bugs in this code (T/F)?: False

  4. What's the output of this code?

I'm skating to Manhattan on my board

  1. Are there bugs in this code? (T/F)?: False

  2. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment