HTML tutorial
CSS3 tutorial
Bootstrap tutorial
JavaScript tutorial
JQuery tutorial
AngularJS tutorial
React tutorial
NodeJS tutorial
PHP tutorial
Python tutorial
Python3 tutorial
Django tutorial
Linux tutorial
Docker tutorial
Ruby tutorial
Java tutorial
C tutorial
C ++ tutorial
Perl tutorial
JSP tutorial
Lua tutorial
Scala tutorial
Go tutorial
ASP.NET tutorial
C # tutorial
Closures (Closures) is a functional self-contained block of code, you can use or be used as a parameter value in the code.
Swift closures in C and Objective-C code blocks (blocks) and some other programming languages anonymous function is quite similar.
Global functions and nested functions is actually a special closure.
Closure of the form:
Global Functions | Nested functions | Expression closures |
I have a name but can not capture any value. | It has a name, but also to capture value within the function closed. | Nameless closure, use lightweight syntax, you can capture the value based on the context. |
Swift closures have a lot of optimization places:
The following defines a receiving parameter and returns the specified type of closure syntax:
{(parameters) -> return type in statements }
import Cocoa let studname = { print("Swift 闭包实例。") } studname()
The above program execution output is:
Swift 闭包实例。
The following closures form takes two parameters and returns a Boolean value:
{(Int, Int) -> Bool in Statement1 Statement 2 --- Statement n }
import Cocoa let divide = {(val1: Int, val2: Int) -> Int in return val1 / val2 } let result = divide(200, 20) print (result)
The above program execution output is:
10
Closures expression is a way to build the use of simple syntax inline closures. Closures expression syntax provides some optimization so that compose the closure becomes simple and clear.
Swift standard library provides a function named sort, it will be sorted according to the closure function you provide will be used to sort the known type values in the array.
After the completion of the sort, sort (_ :) method returns an array of the same size as the original, the new array contains the same type of element and the element has been properly sorted, the original array is not modified sort (_ :) methods.
sort (_ :) method takes two arguments:
true
, contrary to return false
. import Cocoa let names = ["AT", "AE", "D", "S", "BE"] // 使用普通函数(或内嵌函数)提供排序功能,闭包函数类型需为(String, String) -> Bool。 func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } var reversed = names.sort(backwards) print(reversed)
The above program execution output is:
["S", "D", "BE", "AT", "AE"]
If the first character string (s1) is greater than the second string (s2), backwards function returns true, indicating that the new array should appear before s1 s2. For the characters in the string, the "greater than" means "later appear in alphabetical order." This means that the letter "B" is greater than the letter "A", the string "S" is greater than the string "D". It will reverse alphabetical sort, "AT" will be sorted before "AE".
Swift automatically provides an inline function parameter name abbreviation, you can directly through the $ 0 parameter closures of $ 1, $ 2 to call order.
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort( { $0 > $1 } ) print(reversed)
$ 0 and $ 1 for the closure of the first and the second parameter of type String.
The above program execution output is:
["S", "D", "BE", "AT", "AE"]
If you use the parameter name abbreviation in the closure expression, you can closure parameter list its definition is omitted, and the corresponding parameter name Acronym types will be inferred by function type. in keywords it can also be omitted.
In fact there is a shorter way to write the above example closures expression.
Swift's String
type defines on greater-than sign ( >
string) implementation, as a function that takes two String
type parameter and returns a Bool
value type. This coincided with the sort(_:)
type function of the second parameter of the method needs to conform. Therefore, you can simply pass a greater-than sign, Swift can automatically infer that you want to use is greater than the number of string functions to achieve:
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] var reversed = names.sort(>) print(reversed)
The above program execution output is:
["S", "D", "BE", "AT", "AE"]
Trailing closure is a function written in parentheses after the closure of expressions, functions to support its call as the last parameter.
func someFunctionThatTakesAClosure(closure: () -> Void) { // 函数体部分 } // 以下是不使用尾随闭包进行函数调用 someFunctionThatTakesAClosure({ // 闭包主体部分 }) // 以下是使用尾随闭包进行函数调用 someFunctionThatTakesAClosure() { // 闭包主体部分 }
import Cocoa let names = ["AT", "AE", "D", "S", "BE"] //尾随闭包 var reversed = names.sort() { $0 > $1 } print(reversed)
sort () after {$ 0> $ 1} trailing closure.
The above program execution output is:
["S", "D", "BE", "AT", "AE"]
Note: If the function only one parameter expression closures, when you use trailing closures, you can even put
()
omitted.reversed = names.sort { $0 > $1 }
Closures can be constant or variable capture in the context of its definition.
Even the definition of these constants and variables of the original domain does not exist, the closure can still function in vivo closure referencing and modification of these values.
Swift easiest form of closure is nested function, the function is defined in the body of the other functions of the function.
The nested function can capture all of its external function parameters and defined constants and variables.
Look at this example:
func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor }
A function makeIncrementor, it has a parameter of type Int amout, and it has an external parameter name forIncremet, means that when you call, you must use the external name. The return value is a ()-> Int
function.
In the title function, declare a variable and a function runningTotal incrementor.
incrementor function does not get any arguments, but in the body of the function to access the runningTotal and amount variables. This is because it contains the body of the function by capturing its existing runningTotal and variable amount realized.
Since there is no modification amount variable, incrementor actually capture and store a copy of the variable, which is stored together with a copy as incrementor.
So when we call this function will accumulate:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 print(incrementByTen()) // 返回的值为20 print(incrementByTen()) // 返回的值为30 print(incrementByTen())
The above program execution output is:
10 20 30
The above example, incrementByTen is constant, but the point of closure of these constants can still increase the value of its variable capture.
This is because the functions and closures are reference types.
Whether you are a function / closure assigned to a constant or variable, you are actually setting the value of the constant / variable corresponding function / closure references. The above example, incrementByTen closures reference point is a constant, rather than the content of the closure itself.
This also means that if you assign the closure of the two different constants / variables, both values will point to the same closure:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 incrementByTen() // 返回的值为20 incrementByTen() // 返回的值为30 incrementByTen() // 返回的值为40 incrementByTen() let alsoIncrementByTen = incrementByTen // 返回的值也为50 print(alsoIncrementByTen())
The above program execution output is:
50