Closures

作者: 宋奕Ekis | 来源:发表于2021-08-02 17:21 被阅读0次

    Closure Expressions

    The Sorted Method

    let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
    func backward(_ s1: String, _ s2: String) -> Bool {
        return s1 > s2
    }
    var reversedNames = names.sorted(by: backward)
    // reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
    

    the above example shows that we use a backwardfunction as a value to be sent into the sorted function.

    but this is written as a closure ordinarily.

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

    We can see the closures structure:

    { (parameters) -> return type in
    statements
    }

    Inferring Type From Context

    At the above example, the sortedfunction always be called on a strings array, so its argument must be a function of type (String, String) -> Bool, so we don't need to written the whole form.

    It can be written as below:

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

    Implicit Returns from Single-Expression Closures

    And if there only be a single expression in closures, we can omit the return as well.

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

    Shorthand Argument Names

    Simpler and simpler, as below:

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

    Operator Methods

    Simplest!!!

    reversedNames = names.sorted(by: > }
    

    This > can be related to a function, actually, it dose a function.

    Capturing Values

    Warning!!!

    Watch out this expression!

    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()
    // returns a value of 7
    

    We can see the above example, due to the nested function incrementer capture the runningTotal, so runningTotal will remains even if incrementByTen finish, and incrementBySeven is not influenced.

    Because the function type and closures type is reference types.

    Same for closures, but it will may cause strong reference cycles, which we will learn how to solve.

    Escaping Closures

    If we need the closures excute after the function ends, we should use key word @escaping before the parameter’s type.

    var completionHandlers: [() -> Void] = []
    func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
        completionHandlers.append(completionHandler)
    }   
    

    Let’s think!

    相关文章

      网友评论

        本文标题:Closures

        本文链接:https://www.haomeiwen.com/subject/vrjjvltx.html