The Swift Programming Language-detailed description of closure usage, swift closure
A closure is a self-contained function code block that can be passed and used in the code. Closures in Swift are similar to code blocks (blocks) in C and Objective-C, and lambdas functions in other programming languages.
Closures can capture and store references to any constants and variables in their context. This is the so-called closure and enclose these constants and variables, commonly known as closures. Swift manages all memory operations involved in the capture process.
Note:
If you are not familiar with the concept of capturing, you can learn more about it in the Value capture chapter.
The global and nested functions described in the function section are actually special closures. Closures take one of the following three forms:
A global function is a closure with a name but no value is captured.
A nested function is a closure with a name and can capture the values in the function domain.
A closure expression is an anonymous closure that uses lightweight syntax to capture variables or constant values in its context.
The closure expression of Swift has a concise style and encourages syntax Optimization in common scenarios. The main optimization is as follows:
Use context inference parameters and return value types
The closure of a single expression is returned implicitly, that is, the closure of a single expression can omit the return keyword.
Abbreviated parameter name
Trailing closure syntax
Closure expression (Closure Expressions)
Nested functions are convenient in naming and defining self-contained code modules in complex functions. Of course, sometimes it is very useful to write a small class function structure without complete definition and naming, especially when you process some functions and need to use other functions as parameters of the function.
Closure expressions are a method of constructing inline closures using concise syntax. The closure expression provides some syntax Optimizations to make it easy and clear to write the closure. The example of the closure expression below demonstrates the sort function definition and syntax optimization through several iterations. Each iteration describes the same function in a more concise way.
The sort Function)
The Swift Standard Library provides the sort function, which sorts the values in an array of known types based on the closure function of the output type you provide. Once sorting is completed, the function returns a new array of the same size as the original array, which contains the same type of elements that have been correctly sorted.
The following closure expression uses the sort function to sort the letters of a String array in reverse order. The following are the initial array values:
Let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
The sort function requires two parameters:
Array of known types
Closure function, which requires two values of the same type as the array, return a Boolean value to tell the sort function that the first parameter passed in after sorting is placed before or after the second parameter. If the value of the first parameter appears before the value of the second parameter, the sort closure function must return true. Otherwise, false is returned.
This example sorts an array of the String type. Therefore, the type of the sort closure function must be (String, String)-> Bool.
One way to provide the sort closure function is to write a common function that meets its type requirements and pass it as the second parameter of the sort function:
Func backwards (s1: String, s2: String)-> Bool {return s1> s2} var reversed = sort (names, backwards) // reversed is ["Ewa ", "Daniella", "Chris", "Barry", "Alex"]
If the first string (s1) is greater than the second string (s2), the backwards function returns true, indicating that s1 should appear before s2 in the new array. For characters in a string, "greater than" indicates "appearing later in alphabetical order ". This means that the letter "B" is greater than the letter "A", and the string "Tom" is greater than the string "Tim ". It will sort the letters in reverse order, and "Barry" will be placed after "Alex.
However, this is a rather lengthy method, essentially simply writing a single expression function (a> B ). In the following example, we can use the closed expression syntax to better construct an inline sort closure.
Closure Expression Syntax (Closure Expression Syntax)
The syntax of closure expressions is as follows:
{ (parameters) -> returnType in statements}
The closure expression syntax can use constants, variables, and inout types as parameters. default values are not provided. You can also use variable parameters at the end of the parameter list. Tuples can also be used as parameters and return values.
The following example shows the code of the closure expression version corresponding to the backwards function:
reversed = sort(names, { (s1: String, s2:String) -> Bool in return s1 > s2 })
It should be noted that the inline closure parameter and return value type declaration are the same as the backwards function type declaration. Both methods are written as (s1: String, s2: String)-> Bool. However, in an inline closure expression, the types of functions and return values are enclosed in braces, rather than outside braces.
The function body of the closure is introduced by the keyword in. This keyword indicates that the closure parameters and return value type definitions have been completed, and the closure function body is about to begin.
Because the function body of this closure is so short that it can be rewritten into a line of code:
reversed = sort(names, { (s1: String, s2:String) -> Bool in return s1 > s2 } )
This indicates that the overall call of the sort function remains unchanged, and a pair of parentheses still enclose the entire parameter set in the function. One of the parameters is now an inline closure (compared to the backwards version code ).
Inferring Type From Context)
Because the sort closure function is passed as a parameter of the sort function, Swift can infer the type of its parameters and return values. Sort expects the second parameter to be a function of type (String, String)> Bool. Therefore, the String, String, and Bool types do not need to be part of the closure expression definition. Because all types can be correctly inferred, the return arrow (->) and parentheses around the parameter can also be omitted:
reversed = sort(names, { s1, s2 in returns1 > s2 } )
In fact, in any case, when a closure constructed by an inline closure expression is passed to a function as a parameter, the closure parameters and return value types can be inferred, this means that you hardly need to construct any inline closure using the full format.
Implicit Return of a Single Expression closure (Implicit Return From Single-Expression Clossures)
The closure of a single-row expression can implicitly return the result of a single-row expression by hiding the return keyword. The example in the previous version can be rewritten:
reversed = sort(names, { s1, s2 in s1 >s2 } )
In this example, the second parameter of the sort function specifies that the closure must return a Bool value. Because the closure function contains only one single expression (s1> s2), this expression returns the Bool type value, so there is no ambiguity here, And the return keyword can be omitted.
Shorthand Argument Names)
Swift automatically provides the abbreviated parameter name function for inline functions. You can use $0, $1, and $2 to call closure parameters in sequence.
If you use the parameter name abbreviation in the closure expression, you can omit the definition of the parameter in the closure parameter list, and the type of the corresponding parameter name abbreviation is inferred through the function type. The in keyword can also be omitted, because the closure expression is completely composed of the closure function body:
reversed = sort(names, { $0 > $1 } )
In this example, $0 and $1 represent the first and second String parameters in the closure.
Operator Functions)
There is actually a simpler way to write the closure expression in the above example. The String type of Swift defines the implementation of a String greater than (>). As a function, Swift accepts two String-type parameters and returns the value of the Bool type. This exactly matches the function type required by the second parameter of the sort function. Therefore, you can simply pass a greater than sign, and Swift can automatically infer that you want to use a greater than sign string function implementation:
reversed = sort(names, >)