Swift learning closures (closure)

Source: Internet
Author: User



Swift's closures and C,oc block are similar, in fact, the global and nested functions in Swift is actually a special closure, there are three types of closures:



(1) A global function is a closure that has a name but cannot capture any value



(2) Nested functions have a name that can be captured within the function of a worthy closure



(3) The closure expression is a lightweight syntax that captures values from the context



Closure expression is a clean, clear, encouraging introduction to optimized syntax, including:



(1) Infer parameter and return type from context



(2) Simple closure expression can omit return



(3) name of the parameter



(4) Trailing closure syntax



(i) Closure expression



The closure expression is to write an inline package in a concise and accurate way



(ii) Sort function



The SWIFT Standard library provides a sort function to sort arrays of known types, output through the sort package rules you provide





        Let originalnames = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]        var currentnames = Originalnames.sort (backwards)
     let originalNames = ["Chris","Alex","Ewa","Barry","Daniella"]
        var currentNames = originalNames.sort(backwards)
    func backwards(s1: String , s2: String) -> Bool {
        return s1 > s2
    }

It's a bit of a long-winded, but it's a good and suitable chestnut.





Let's use closures to express





 var reverse = originalNames.sort({ (s1: String , s2: String) -> Bool in
            
            return s1 > s2
            
        })
Explanation: (1) in the preceding is the parameter type and the return value type





(2) in the back is the implementation part



(3) The entire expression is enclosed in the {} number.



Because Swift has inferred type functionality, closures can infer types from the context, so the above expressions can also be written as:





    var reverse = originalNames.sort({s1 , s2 in return s1 > s2})
        print(reverse)
In addition, a single-line expression can omit the return keyword, so the above expression can be written as:







   var reverse = originalNames.sort({s1 , s2 in s1 > s2})
        print(reverse)
With the sort function and the second parameter of sort we know that this function must return a bool type, the return value has only one single expression, so return can be omitted and will not cause ambiguity





(c) The name of the parameter



Swift provides a shorthand for the parameter name for the inline package, which is used to correlate parameters, so how do you see the shorthand name? Is $0,$1,$2 ....



If you write the closure of the expression with a shorthand name, then you write all the parameters can be saved, because they have been equivalent to provide you with parameters, just shorthand, you do not have to write, write the TM wasted affection ah, not only waste their own, but also a waste of swift, especially the programmers, I have closed the package into this, You do not write so troublesome mess, the province of everyone is in the heart of the panic, nonsense not much to say, the following test this shorthand:





 var reverse = originalNames.sort( { $0 > $1 } )
        print(reverse)

0,1 this is starting from the first parameter association, everyone is dry program, know that the program is starting from 0, you ask why, I can only hehe





(iv) operator (some also called operator) function



Since Swift's string type has a comparison of two characters, and the type of bool is returned, so we can write it a little bit more simply, pass an operator (operator), and Swift will infer itself by invoking the implementation of the string itself.





         var reverse = Originalnames.sort (>)

Five Trailing (tail) closure





The meaning is to put the closure implementation in the tail to write, why should be placed in the tail, because the closure is too long, may affect the readability of the code, aesthetics, so put it on the last side of the implementation of the



The swift array has a map (map) method, which simply passes the closure expression as a parameter. The closure iterates through each element of the array and returns a mapping of the corresponding optional type. The core of the map and the type of the return value are both closures. When the map method is used, a new array is returned, which contains all the new values of the mappings, an example of which is the conversion of an int array to an array of type Strin, which illustrates:





   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() {
            (var number) -> String in
            var output = ""
            while number > 0 {
                output = digitNames[number % 10]! + output
                number /= 10
            }
            return output
        }
        
        print(strings)
Explanation: First declare a dictionary, declare an array, call the map method, write your own implementation





Second, by Return,swift, it has been inferred that strings is a string-type array.



Finally, I'll look at the print results.



If the closure is the only parameter of the function, the parentheses after the function can be omitted, so the above function can also be written like this:





      let strings2 = numbers.map {
            (var number) -> String in
            var output = ""
            while number > 0 {
                output = digitNames[number % 10]! + output
                number /= 10
            }
            return output
        }
        
        print(strings2)

Here, the number in front of the use of Var decoration, this in the function, is called in the internal variable, the equivalent of declaring a variable inside the function, and the number (the element of the array) passed to the variable, the function call ends, he also released the





The specified return type is a string type, stored in the returned array.



Note: The above dictionary is followed by an exclamation point, because the dictionary under the banner method always returns an optional value if the query fails, but in the above example, be sure to ensure that the dictionary subscript value is valid, so we want to force the unpacking, to get stored in the optional return value of the string type value



(vi) Value capture



To put it bluntly, a closure can capture values from the context, use it for its own use (variable constants can, and change its value yourself), and here's an example of a simple function nesting





 let incrementByTen = makeIncrementer(forIncrement: 10)
        print(incrementByTen())
    }

    func makeIncrementer(forIncrement amout: Int) -> Void -> Int {
        
        var runningTotal = 0
        
        func increment() -> Int {
            runningTotal += amout
            return runningTotal
        }
        
        return increment
    
    }
Func increment () This function captures the values of runningtotal and amout, and makeincrementer This function returns a function type (a function that does not receive a parameter and returns a value of type int)
  let incrementByTen = makeIncrementer(forIncrement: 10)
        incrementByTen()
        incrementByTen()
        print(incrementByTen())
What's the result of the above print guess? This is because the closure automatically helps us store the value of the variable, and the same function will be added automatically, if we define a function again? For example, the following two output results







   let incrementBySeven = makeIncrementer(forIncrement: 7)
        incrementByTen()
        print(incrementByTen())
        print(incrementBySeven())
It is learned from the above that we define a function closure to reference a new value to the new function, and the previous function will not be confused, but the original or perform its own function





Note: If we define a closure as a property of an instance of a class, by referencing the instance or its members, a strong reference will be generated, but given the solution, I'll explain it later, thank you.



(vii) Closures are reference types



In the above example, Incrementbyten and Incrementbyseven are constants, but the closures they refer to can still change the value of RunningTotal because the functions and closures are reference types, When we assign a function or a closure to a constant or variable, we actually use the constant or variable to refer to the closure, and the print call is also used, in the code below the RunningTotal value has been + 10,


        Let Alsoincrementbyten = Incrementbyten
This alsoincrementbyten is the result of incrementbyten+10, do not believe that you can try





Okay, I'm done with the closures, and next time I'll introduce the enumeration in Swift.



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.



Swift learning closures (closure)


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.