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


Related articles: