Closures for Swift 3.0 basic learning
- 2020-05-24 06:18:19
- OfStack
preface
Closures are functional self-contained modules that can be passed and used in code. Closures in Swift are similar to blocks in C and Objective-C, and lambdas in some other programming languages. The following article details the closures in Swift 3.0. Take a look at the ones that interest you.
start
The closure is written as follows:
{ (parameters) -> return type in
statements
}
Such as
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
When used, it can be reduced to
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
Or we could simplify it to
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
It could even be reduced to
reversedNames = names.sorted(by: { $0 > $1 } )
$0 is the first parameter, and so on
Return Boolean value can be directly given to 1 judgment symbol, such as
reversedNames = names.sorted(by: >)
The rear closure
reversedNames = names.sorted() { $0 > $1 }
Or (with no other parameters)
reversedNames = names.sorted { $0 > $1 }
Either way is fine
Capture value
In the following code, a closure can acquire and modify the variables around it
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
The above function returns a closure with an external variable runningTotal added to read and modify the closure
let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
// returns a value of 30
Closure reference type
You can refer to closures in this way and call:
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
0
@escaping
If the closure passed to a function is called not inside the function, but inside the function with an external variable to hold the current closure and call it at the appropriate time, the @escaping keyword needs to be added before the closure argument, otherwise the compiler will report an error.
It is easy to understand that network requests are frequently used, and the completed closure is executed only after the request is completed.
The official example is as follows:
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
1
autoclosure automatic closure
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
2
As shown in the code above, we add a closure that returns type String, which needs to be surrounded by {}, which can be omitted for ease of writing by adding the @autoclosure keyword.
// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// Prints "Now serving Ewa!"
The compiler will flag this line of code as a closure, which is not called immediately, but only when the closure is called inside the function.
Reference:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94
conclusion