16. Closure

2016. 10. 8. 14:09Swift

// Closures


// Closures Expressions

// The Sorted Method

let names = ["Chris", "Alex", "Ewa", "Barry", "Deniella"]


func backward(_ s1: String, _ s2: String) -> Bool {

    return s1 > s2

}


var reversedNames = names.sorted(by: backward) // 문자열 정열


// Closure Expression Syntax

//{ (parameters) -> return_type in

//   statements

//}


// 함수명을 절로 바꿨다.

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )


// Inferring Type From Context

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )


// Implicit Returns from Single-Expression Closures

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )


// Shorthand Argument Names

reversedNames = names.sorted(by: { $0 > $1 } )


// Operator Methods

reversedNames = names.sorted(by: > )


// Trailing Closures


func someFunctionThatTakesAClosure(closure: () -> Void) {

    // function body goes here

}


someFunctionThatTakesAClosure(closure: {

    // closure;s body goes here

})


someFunctionThatTakesAClosure() {

    // trailing closure's body goes here

}


reversedNames = names.sorted() { $0 > $1 }

reversedNames = names.sorted { $0 > $1 }


let digitNames = [

    0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",

    5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"

]


let numbers = [16, 58, 510]


let strings = numbers.map {

    (number) -> String in

    var number = number

    var output = ""

    

    repeat {

        output = digitNames[number % 10]! + output

        number /= 10

        

    } while number > 0

    return output

}


// Capturing Value


func makeIncrementer(forIncrement amount: Int) -> () -> Int {

    var runningTotal = 0

    

    func incrementer() -> Int {

        runningTotal += amount

        return runningTotal

    }

    

    return incrementer

}


let incrementByTen = makeIncrementer(forIncrement: 10)


incrementByTen() // returns a value of 10

incrementByTen() // returns a value of 20

incrementByTen() // returns a value of 30


let incrementBySeven = makeIncrementer(forIncrement: 7)


incrementBySeven()


incrementByTen()


// Closures Are Reference Types

let alsoIncrementByTen = incrementByTen

alsoIncrementByTen()


// Escaping Closures

var completionHandlers: [() -> Void] = []


func someFunctionWithEscapingClosure(completionHandler: @escaping() -> Void) {

    completionHandlers.append(completionHandler)

}


func someFunctionWithNonescapingClosure(closure: () -> Void) {

    closure()

}


class SomeClass {

    var x = 10

    

    func doSomething() {

        someFunctionWithEscapingClosure { self.x = 100; print("1") }

        someFunctionWithEscapingClosure { self.x = 111; print("2") }

        someFunctionWithNonescapingClosure { self.x = 200; print("3") }

    }

}


let instance = SomeClass()

instance.doSomething()

print(instance.x)


completionHandlers.first?()

print(instance.x)


// Autoclosures

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]


print(customersInLine.count)


let customerProvider = { customersInLine.remove(at: 0) }

print(customersInLine.count)


print("Now serving \(customerProvider())!")

print(customersInLine.count)


func serve(customer customerProvider: () -> String) {

    print("Now serving \(customerProvider())!")

}


serve(customer: { customersInLine.remove(at: 0) } )

print(customersInLine.count)


func serve(customer customerProvider: @autoclosure() -> String) {

    print("Now serving \(customerProvider())!")

}


serve(customer: customersInLine.remove(at: 0))

print(customersInLine.count)


var customerProviders: [() -> String] = []

func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {

    customerProviders.append(customerProvider)

}


collectCustomerProviders(customersInLine.remove(at: 0))

collectCustomerProviders(customersInLine.remove(at: 0))


print("Collected \(customerProviders.count) closures.")


for customerProvider in customerProviders {

    print("Now serving \(customerProvider())!")

}


출처 : The Swift Programming Language(iBook)