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      

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.