first, closure of the introduction
- Closure expressions (Closure Expressions)
- Trailing closures (Trailing Closures)
- Value capture (capturing values)
- Closures are reference types (Closures is Reference Types)
Closures are self-contained function code blocks that can be passed and used in code. Closures in Swift are similar to the Lambdas functions in the code blocks (blocks) in C and Objective-c, and in some other programming languages.
Closures can capture and store references to any constants and variables in the context in which they are located. This is called closed merge wrapped with these constants and variables, commonly known as closures. Swift manages all of the memory operations involved in the capture process for you.
Global and nested functions are actually special closures, and closures take one of the following three forms:
- A global function is a closed packet that has a name but does not capture any value
- A nested function is a closure that has a name and can capture values within its enclosing function domain
- A closure expression is an anonymous closure that uses lightweight syntax to capture variables or constant values in its context.
Swift's closure expressions have a concise style and encourage syntax optimization in common scenarios, mainly optimized as follows:
- Infer parameters and return value types with context
- Implicitly returns a single-expression closure, where a single-expression closure can omit the return keyword
- Parameter name abbreviation
- Trailing (Trailing) closure syntax
Ii. Examples
1, sorted function, sorted function needs to pass in two parameters:
An array of known types, a closure function that needs to pass in two values that are the same as the array type, and returns a Boolean value that tells the sorted function whether the first parameter passed in after the sort finishes is preceded or followed by the second argument. If the first parameter value appears before the second parameter value, the sort closure function needs to return true and vice versa to return False
This is a rather lengthy way of essentially just writing a single expression function (a > B)
Let names = ["Chris","Alex","Ewa","Barry","Daniella"]func Backwards (s1:string, s2:string)-bool{returnS1 >S2}var Reverse=names.sort (backwards) print ("descending: \ (reverse)")
2. Closed-Packet expression syntax
The closure expression syntax has the following general form
{(parameters)-ReturnType in
Statements
}
The closure expression syntax can use constants, variables, and inout types as parameters, and does not provide a default value. You can also use variable parameters at the end of the parameter list. Tuples can also be used as parameters and return values.
inch return s1 < s2}) print (" ascending: \ (reverse)")
3. Inferred type based on context
Because the sort closure function is passed in as a parameter to the sorted function, Swift can infer the type of its parameter and return value. Sorted expects the second argument to be a function of type (string, string), bool, so the fact that the string,string and bool types do not need to be part of the definition of the closure expression. Because all types can be inferred correctly, the return arrows (-a) and the parentheses around the parameters can also be omitted:
In fact, in any case, when a closure constructed with an inline closure expression is passed as a parameter to a function, the parameters and return value types of the closure can be inferred, which means that you hardly need to construct any inline closures with the full format.
inch return s1 > s2}) print (" descending: \ (reverse)")
4. Single-expression closed Baoyin return
A single-line expression closure can implicitly return the result of a single-line expression by hiding the return keyword, as the previous version of the example can be rewritten as
In this example, the second argument function type of the sorted function is clear that the closure must return a bool type value. Because the closure function body contains only a single expression (S1 > S2), the expression returns the bool type value, so there is no ambiguity and the return keyword can be omitted.
in S1 < S2}) print (" ascending: \ (reverse)")
5. Parameter name abbreviation
Swift automatically provides parameter name abbreviations for inline functions, and you can call the closure parameters directly from $0,$1,$2.
If you use a parameter name abbreviation in a closure expression, you can omit the definition of it in the closure parameter list, and the type that corresponds to the abbreviation for the parameter name is inferred from the function type. The In keyword can also be omitted, because at this point the closure expression is completely composed of the closure function body:
Reverse = Names.sort ({$0 > $1 })/// In this example, the $ $ and $ $ represent the first and second string arguments in the closure. print (" descending: \ (reverse)")
6. Operator functions
There is actually a shorter way to write the closure expression in the example above. Swift's string type defines an implementation of the strings for the greater-than sign (>), which takes two arguments of type string as a function and returns a value of type bool. This coincides with the type of function required for the second argument of the sorted function. Therefore, you can simply pass a greater than sign, and Swift can automatically infer that you want to use a string function that is greater than the number:
Reverse = Names.sort (< ) print (" ascending: \ (reverse)")
7, trailing closure package
If you need to pass a long closure expression as the last argument to a function, you can use a trailing closure to enhance the readability of the function. A trailing closure is a closure expression that is written after the function brackets, and the function supports calling it as the last argument.
Func somefunctionthattakesaclosure (Closure: () ) {// function body part closure () }
// The following is a function call that does not use a trailing closure somefunctionthattakesaclosure ({ // closure body part print (" First:closure closure function called ")})/// The following is a function call using a trailing closure somefunctionthattakesaclosure { // closures body part print ("Second: The closure closure function was called ")}
Note: If the function needs only one parameter of the closure expression, you can even omit () when you use a trailing closure.
Example: Reverse = Names.sort ({$ > $})
Trailing closures are useful when closures are so long that they cannot be written on a single line. For example, the array type of Swift has a map method that gets a closure expression as its only parameter. Each element in the array is called once for the closure function and returns the value that the element is mapped to (or a different type of value). The specific mapping method and return value type are specified by the closure.
When supplied to the array closure function, the map method returns a new array containing the mapped values corresponding to the original array one by one.
Let Digitnames = [ 0:"Zero",1:" One",2:" Both",3:"three",4:" Four", 5:"Five",6:"Six",7:"Seven",8:"Eight",9:"Nine"]let Numbers= [ -, -,510]func printoutput ()-Void {Let strings=Numbers.map {(var number)-Stringinchvar output="" whileNumber >0{Output= Digitnames[number%Ten]! +Output Number/=Ten } returnOutput} print (strings)}printoutput ()
8. Capture Value
Closures can capture constants or variables in the context in which they are defined. Even though the original domain that defines these constants and variables does not already exist, closures can still reference and modify these values in the closure function body.
Swift's simplest form of closure is a nested function, which is a function defined in the function body of another function. A nested function captures all parameters of its outer function, as well as the constants and variables defined.
Func makeincrementor (forincrement amount:int), int{0 , int{ + = amountreturn runningtotal } return Incrementor}
Note: Swift determines whether to capture a reference or copy a value. You do not need to label amount or runningtotal to declare how you want to use the embedded Incrementor function. Swift also handles the memory management operations of the runingtotal variable, which is cleared if it is no longer used by the Incrementor function.
Ten ) Print (Incrementbyten ()) Print ( incrementbyten ()) print (Incrementbyten ())
Third, printing results:
Descending: ["Ewa","Daniella","Chris","Barry","Alex"] Ascending: ["Alex","Barry","Chris","Daniella","Ewa"] Descending: ["Ewa","Daniella","Chris","Barry","Alex"] Ascending: ["Alex","Barry","Chris","Daniella","Ewa"] Descending: ["Ewa","Daniella","Chris","Barry","Alex"] Ascending: ["Alex","Barry","Chris","Daniella","Ewa"The]first:closure closure function was called and the second:closure closure function was called ["Onesix","Fiveeight","Fiveonezero"]Ten - -
Swift: Closures