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

SOLVED: Stuck - Closures with Parameters!

Forums > 100 Days of Swift

OK, So I've done alright thus far, that is until I reached Day 7 and found this code:

func travel(action: (String) -> Void) {
    print("I'm getting ready to go.")
    action("London")
    print("I arrived!")
}

travel { (place: String) in
    print("I'm going to \(place) in my car")
}

I can't seem to understand how we place "London" in the action argument which is then picked up when calling Travel. Since 9am today (it's now 18:50) I've been reading countless articles, watching numerous YouTube videos and I still can't understand. Why are we placing "London" in action() when we're later printing "I'm going to (place) in my car"?

If anyone is able to help simplify this, I'd be most gratful.

Many thanks,

Simon

4      

The travel function takes a closure, called action, with a String parameter, indicated by the parameter type (String) -> Void. So when you call the closure called action, you have to pass it a String, "London" in this case.

Think of it this way...

Essentially, using a closure as a parameter creates a function of that name and you call it like you would if you had written it as a function.

So the action: (String) -> Void parameter and passing the trailing closure in the example code is the same as writing a function like this:

func action(place: String) {
    print("I'm going to \(place) in my car")
}

And just like you would call that function as action("London"), you call the closure the same way.

4      

@roosterboy - thank you very much for your detailed response.

3      

Something that really helped me was to ask myself, "How would I get the same result without using trailing closure syntax in the call?" The error messages generated by Xcode in my many attempts led me to the answer. Here's what I got (but, really, work it out for yourself first):

func travel(action: (String) -> Void) {
    print ("I'm getting ready to go.")
    action("London")
    print ("I arrived!")
}

// call with trailing closure
travel { (place: String) in
    print ("I'm going to \(place) in my car.")
}

// explicit, named closure
let byCar = { (place : String) in   //why doesn't this have to be a var declaration?
    print ("I'm going to \(place) in my car.")
}

// call using explicit closure
travel (action: byCar )

Anyone understand why byCar works as a constant? Even if the travel function is modified to call action() multiple times with different places, nothing complains.

3      

You assigned a closure to byCar that matches the type signature of the action parameter, so it works just as if you had supplied the closure itself in the parameter.

It can be either a constant or a variable; the difference being that if it's a var you can reassign a new closure (with the same type signature, of course) to byCar but if it's a let you cannot. Being a constant or a variable doesn't mean anything to the contents of the closure, just to the identifier that points at it.

4      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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.