Day 7 – Closures Part Two

// closures recap
// a closure is a function without a name, which can be passed around like a value. let's create a simple closure

let myClosure = {
    print("Hi!")
}

// we can create a function which accepts a closure as parameter like so:
func thisFunctionAcceptsAClosure(closure: () -> Void) {
    closure()
}

// then we call the function
thisFunctionAcceptsAClosure { // given that the function accepts a closure as its last parameter, and the closure does not accept parameters itslf nor does it return anything, we can use this syntax called trailing closure syntax.
    print("Hi!")
}

// closures themselves can accept parameters and return values. This one does both

func thisFuncGetsASuperClosure(superClosure: (String) -> String) {
    superClosure("Piece of text")
}

thisFuncGetsASuperClosure { (text: String) -> String in
    return "Are we going to \(text)?"
}

// shorthand parameter names
// swift is pretty smart when it comes to understanding closures as parameters. let's see that in action with thisFuncGetsASuperClosure

thisFuncGetsASuperClosure { text in // swift knows the parameter and return types because we specified them earlier
    return "Are we going again to \(text)?"
}

// we can go a step further. closure parameters are automatically assigned a shorthand by swift like so:

thisFuncGetsASuperClosure {
    "Are we going to \($0) again and again?"
}
// we even removed the "return" keyword since there is only one line of code in the closure. it must then be the return value.

// multiple parameter closures

func funcThatAcceptsClosureWithTwoParameters(action: (String, Int) -> String) {
    print("I'm about to print something out from that closure with two parameters.")
    print(action("London", 12))
}

funcThatAcceptsClosureWithTwoParameters {
    "I am going to \($0) at this speed: \($1)."
}

// returning a closure from a function
func thisFunctionReturnsAClosure() -> (String) -> Void {
    return {
        print("Closure pros: \($0)")
    }
}

let myClosure2 = thisFunctionReturnsAClosure()
myClosure2("Incredible!")

// capturing values
// let's create a function that returns a friendly closure. this time, we will
// also put a counter, which will count up every time the closure is run.
// the counter is declared in travel()

func travel() -> (String) -> Void {
    var counter = 0
    return {
        print("\(counter). Hi, \($0).")
        counter += 1
    }
}

let travelClosure = travel()
travelClosure("Milan")
travelClosure("Milan")
travelClosure("Milan")
travelClosure("Milan")

// as you can see, the counter goes up even though it's not stored inside the closure. This is because the closure captured it.

Leave a Reply

Your email address will not be published. Required fields are marked *