Deep understanding of the closure mechanism in Swift language _swift

Source: Internet
Author: User
Tags closure


Closures in Swift are similar to structural blocks and can be invoked anywhere, like functions built into C and objective C. Constants and variable references defined within a function can be captured and stored in closures. A function is considered a special case of closure, which has 3 different forms.






In Swift language closure expressions, such as under optimization, lightweight grammatical style, which includes:


    • To derive a parameter and return the type of the value from the context menu
    • Implicit return from a single expression
    • Abbreviated parameter name
    • Tail closure syntax


Grammar
The following is a generic syntax definition for closures, which takes parameters and returns the type of data:


code as follows:

{(parameters)-> return type in
Statements
}

The following is a simple example:
code as follows:

Let Studname = {println ("Welcome to Swift Closures")}
Studname ()

When we use playground to run the above program, we get the following results




Welcome to Swift Closures


The following closures accept two parameters and return a Boolean value:


 code as follows:

{(int, int)-> Bool in
Statement1
Statement 2
---
Statement N
}

The following is a simple example:
 code as follows:

Let divide = {(Val1:int, val2:int)-> Int in
Return Val1/val2
}
Let result = Divide (200, 20)
println (Result)

When we use playground to run the above program, we get the following results




10


Expressions in closures
a convenient way to define a code block can be implemented through nested functions. Instead represent the entire function declaration and the name construct to represent the function. The syntax for representing a function is clear, and a short statement is achieved by enclosing the expression.



Arrange programs in ascending order
the sort string is the function "sorted" reserved in Swift, which is provided in the standard library. The function sorts the given string in ascending order and returns elements of a new array of the same data type in the old array. The old array remains unchanged.



The ordering of two parameters is represented inside the function:



Values of known types represent arrays



The contents of the array (Int,int) and returns a Boolean value (Bool) that returns true if the array is not sorted well, or false.



The ordinary function with the input string is written and passed to the sort function to get the character to the new array as shown below:


 code as follows:

Func Ascend (s1:string, s2:string)-> Bool {
return s1 > S2
}
Let stringcmp = Ascend ("Swift", "great")
println (STRINGCMP)

When we use playground to run the above program, we get the following results







 code as follows:


True





The initial array ordering is given "Swift" and "great". The function used to sort the array is declared as a string data type, and the return type is Boolean. Two strings are compared and sorted in ascending order and stored in the new array. If the sort execution succeeds, the function returns True, otherwise it returns false.


Closed-Package Expression syntax usage



Constant parameters:



Variable parameters and InOut parameters



The closure expression does not support default values. Variable parameters and parameter tuples can also be used as parameter types and return types.


 code as follows:

Let sum = {(No1:int, no2:int)-> Int
Return No1 + NO2
}
let digits = SUM (10, 20)
println (digits)

When we use playground to run the above program, we get the following results




30


The arguments and return type declarations mentioned in the function declaration can also be expressed by using an inline closure expression function in the ' in ' keyword. Once you declare the parameter and its return type "in" keyword, it is used to represent the closure body.



An implicit return of a single expression
here, the function type of the second parameter of the sort function clearly states that a Boolean value must be returned by the closure. Because the closure contains an expression (S1 > S2) that returns a Boolean value, there is no ambiguity and the return keyword can be omitted.



To return an expression statement in the closure, the ' return ' keyword is omitted in its declaration section.


 code as follows:

Let count = [5, 10,-6, 75, 20]
var descending = sorted (count, {n1, N2 in N1 > n2})
var ascending = sorted (count, {n1, N2 in N1 < N2})


println (Descending)
println (Ascending)


When we use playground to run the above program, we get the following results




[5, 6]
[-6, 5, 10, 20, 75]


The statement itself explicitly stipulates that when string1 is greater than string2 returns TRUE, otherwise it is false, so the return statement is omitted.



Closed packages of known types
Consider the addition of two numbers. We know that the addition will return the integer data type. As a result, the closed-package declaration of a known type


 code as follows:

Let sub = {(No1:int, no2:int)-> Int
Return No1-no2
}
Let digits = Sub (10, 20)
println (digits)

When we use playground to run the above program, we get the following results




-10


Declaring a shorthand parameter name as a closure
Swift automatically provides the abbreviated parameter name inline closure, which can be used by $0,$1,$2 and so on, referring to the enclosing parameter value.


 code as follows:

var shorthand: (String, String)-> String
Shorthand = {$}
println (Shorthand ("100", "200"))

Here, the first and second string parameters of the $ and reference closures.





When we use playground to run the above program, we get the following results


200


Swift facilitates the user to indicate that an inline closure is abbreviated with the name: $, $, $---$n.



The definition section is omitted in the closure parameter list when we represent the internal closure expression shorthand parameter name. The name of the parameter is exported based on the function type. The ' in ' keyword defined by the shorthand parameter expression is omitted.



Closure as an operational function
Swift provides a simple way to access members by simply providing operator functions as closures. In the previous example the keyword "Bool" is used to compare two strings, the equality returns "true", otherwise returns "false".



An expression is simple in the operation function even in the closure:


 code as follows:

Let numb = [98,-20,-30, 42, 18, 35]
var sortednumbers = numb.sorted ({
(Left:int, Right:int)-> Bool in
Return to left < right
})
Let ASC = Numb.sorted (<)
println (ASC)

When we use playground to run the above program, we get the following results




[-30,-20, 18, 35, 42, 98]



Closures as trailing packages
pass the last argument of this function to the closed expression using a "trailing closure" declaration. It is written with {} outside the function (). When it cannot write to a function inline on one line, using it is required.


 code as follows:

Reversed = sorted (names) {$ > $}

where {$ >} is represented as an external (name) declaration trailing closure.
 code as follows:

Import Foundation
var letters = [' North ', ' East ', ' West ', ' South ']

Let Twoletters = Letters.map ({(state:string)-> String in
Return State.substringtoindex (Advance (State.startindex, 2)). uppercasestring
})
Let stletters = Letters.map () {$0.substringtoindex (Advance ($0.startindex, 2)). Uppercasestring}
println (Stletters)

When we use playground to run the above program, we get the following results




[NO, EA, WE, so]


Capturing values and reference types
Swift completes the capture of constants and variables with the help of closures. It also references modified values, even if constants and variables do not exist in the closure.



Capturing constants and variable values are written by using nested functions, which are implemented using other function bodies:


    • A nested function capture
    • External function arguments
    • To catch variables defined in constants and external functions


When a constant or variable is declared in a function in Swift, the reference to the variable is also automatically closed for creation. It also provides tools to reference more than two variables as the same closure as follows:


 code as follows:

Let Decrem = Calcdecrement (fordecrement:18)
Decrem ()

Here, the onedecrement and decrement variables all point to the same block of memory for a closed reference.
 code as follows:

Func calcdecrement (fordecrement total:int)-> ()-> Int {
var overalldecrement = 100
Func decrementer ()-> Int {
Overalldecrement = Total
println (overalldecrement)
Return overalldecrement
}
Return Decrementer
}
Let Decrem = Calcdecrement (fordecrement:18)
Decrem ()
Decrem ()
Decrem ()

When we use playground to run the above program, we get the following results:




46


The Decrementer () function is called when each external function calcdecrement called, and the result is returned with the help of the external function calcdecrement, by decreasing the value 18. Here, calcdecrement as a closed.



Even if the function decrement () does not have any arguments, the closure by default refers to the "overall decrement" "Total" of the variable by obtaining its value. A copy of the value for the specified variable is stored with the new Decrementer () function. Swift allocates and frees memory space by processing memory management functions when variables are not used.




Here is a wave of summary ~


 code as follows:

/* Closure (Closures)
* Closures are self-contained functional code blocks that can be used in code or used as parameters to pass values.
* The closures in Swift are similar to those in C, OC blocks and other programming languages such as Python lambdas.
* Closures can capture and store references to any constants and variables defined in the context. This is called the variable and the variable's self blocking,
* So named "Closure" ("Closures)"). Swift also handles memory management for all the captured references.
*
* Global functions and nested functions are actually special closures.
* Closures are in the form of:
* (1) Global functions are closures that have a name but cannot capture any value.
* (2) Nested functions are closures and have names that capture the values within the enclosing function.
* (3) Closure expressions are anonymous closures, using lightweight syntax to capture values based on context environments.
*
* There are a number of optimizations for closures in Swift:
* (1) Infer parameters and return value types based on context
* (2) implicitly return from a Single-line expression closure (that is, the closure has only one line of code and can be omitted)
* (3) can use a simplified parameter name, such as $, (starting from 0, representing the first parameter ...)
* (4) provides a trailing closure syntax (trailing closure syntax)
*/

The following is a step-by-step simplification of closure notation using the Sort method in the Swift standard library
The sort function requires two parameters
Parameter one: array
Parameter two: A closure: With two parameters, the two parameter types are the same as the element types in the array, and the return value is bool
var names = ["Swift", "Arial", "Soga", "Donary"]

The first way: using functions
Func Backwards (firststring:string, secondstring:string)-> Bool {
return firststring > secondstring//Ascending sort
}
Here's the second argument, which passes a function
Reversed is equal to [Swift, Soga, Donary, Arial]
var reversed = sort (nams, backwards)

The second way: using the closure method
The complete closure is written in curly braces with parameter lists and return values, with the keyword in indicating the beginning of the closure
(firststring:string, secondstring:string) List of closure parameters
-> BOOL indicates that the closure return value type is bool
The In keyword indicates the beginning of the closure.
Reversed = sort (names, {(firststring:string, secondstring:string)-> Bool in
return firststring > Secondstring
})





This can be further simplified because the closure code is shorter and can be written on one line
Reversed = sort (names, {(firststring:string, secondstring:string)-> Bool in return firststring > secondstring})

The following is further simplified: automatic inference of types based on environment context
The argument list does not indicate a type, nor does it indicate a return value type, because Swift can be used to measure
The type of firststring and secondstring will be the type of the names array element, and the return value type will be based on the returns statement
Reversed = sort (names, {firststring, secondstring in return firststring > secondstring})



Further simplification: implicit return (single-line statement closure)
Because the closure has only one line of code, you can omit return
Reversed = sort (names, {firststring, secondstring in Firststring > secondstring})



Further simplifying: Using simplified parameter names ($i, i=0,1,2 ... starting from 0)
Swift infers that the closure requires two parameters, the same type as the names array element
Reversed = sort (names, {$ > $})


The simplest kind of writing: using the operator
Reversed = sort (names, >)


/*
* Trailing closures (trailing Closures)
* If the function requires a closure parameter as a parameter, and this parameter is the last parameter, and the closure expression is very long,
* It is useful to use a trailing closure. A trailing closure can be placed outside the function argument list, which is outside the parentheses. If the function has only one argument,
* then the brackets () can be omitted, followed by the closure directly.
*/
Array's method map () requires a closure as a parameter
Let strings = Numbers.map {//Map function after () can omit
(var number)-> String in
var output = ""
While number > 0 {
Output = String (number%) + output
Number/= 10
}
Return output
}

/* Capture Value
* Closures can capture the defined constants and variables based on the environment context. Closures can refer to and modify these captured constants and variables,
* Even if defined as a constant in the original range or the variable no longer exists (very cool).
* The simplest form of closure in Swift is nested functions.
*/
Func increment (#amount: int)-> (()-> int) {
var total = 0
Func incrementamount ()-> Int {
Total + = amount/Total is a variable in the external function body, which can be captured here.
Return Total
}
return Incrementamount//Returns a nested function (closure)
}

Closures are reference types, so Incrementbyten declared as constants can also modify total
Let Incrementbyten = Increment (amount:10)
Incrementbyten ()//Return 10,incrementbyten is a closed package
Here is no change to the increment reference, so the previous value will be saved
Incrementbyten ()//Return 20
Incrementbyten ()//Return 30


Let Incrementbyone = Increment (amount:1)
Incrementbyone ()//return 1
Incrementbyone ()//return 2
Incrementbyten ()//Return 40
Incrementbyone ()//Return 3







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.