UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Day 7.1 - Test question

Forums > 100 Days of SwiftUI

Hello All,

As I'm mixing my education from Paul's books, internet sources and 100 Days of SwiftUI, I tend to return to the topics where I believe I need more practice with the basics. Closures are one of those topics and I'm trying to re-educate myself after 2+ years with Java. I'm wondering if you could help me catch what's happening with the code from question 8/12 from the Test:

func getDirections(to destination: String, then travel: ([String]) -> Void) {
    let directions = [
        "Go straight ahead",
        "Turn left onto Station Road",
        "Turn right onto High Street",
        "You have arrived at \(destination)"
    ]
    travel(directions)
}
getDirections(to: "London") { (directions: [String]) in
    print("I'm getting my car.")
    for direction in directions {
        print(direction)
    }
}

It's a valid code, but is it the most optimal one? Could someone tell me how to interpet what's happening there? My understanding:

  1. We create getDirections function that accepts String and a closure as parameters. The closure accepts an Array of Strings and returns nothing (Void).
  2. The closure inside function accepts the directions array and uses functions destination parameter
  3. getDirections function gets called, we declare "London" as a destination -> here's where I'm confused

I'm not exactly sure if that's the way to handle it, but I would prefer function getDirections to handle everything and be handled with a simple call of getDirections(to: "London").

Any hints how to redirect my mindset will be highly appreciated! :)

2      

Hi, when I was trying to understand closures, the following three-step concept helped me get it:

  1. You define the closures "skeleton", that is the signature. In the above case that is ([String]) -> Void. It just says what parameters this closure accepts (an array of strings) and what it returns (in this case nothing).

  2. The calling of the closure is sub-divided into two steps:

a. In the function's (getDirections) body, you define a call-site for the closure where you pass in the 'directions' parameter. At this point the closure doesn't actually have a body yet, but that's okay because the closure isn't called until the function itself (getDirections) is called at a later point of your chosing.

b. At the function's (getDirections) call site, you use trailing closure syntax to actually define what happens inside the closure and thus give it a body. The parameter has already been passed in in step a.

You could say the compiler evaluates the getDirections function's body, hits the closure with the passed-in parameter and then looks at what you defined (within the trailing closure syntax) as that closure's body to understand what to do with that passed-in parameter.

I hope that makes sense.

3      

Hi @ddaehling, it definitely makes sense and helps a lot! I think with your approach and everything I've read it should get easier for my head to process it. I'm marking the thread as solved and if I have any further questions, I'll definitely be back here.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.