closure

Closures are self-contained blocks of functional code that can be passed and used in code. Closures in Swift are similar to code blocks in C and Objective-C, and anonymous functions in some other programming languages (Lambdas).

Swift’s closure expressions have a concise style and encourage syntactic optimizations in common scenarios. The main optimizations are:

  • Use context to infer parameter and return value types
  • Implicitly returns a single-expression closure, that is, the single-expression closure can be omittedreturnThe keyword
  • Parameter name abbreviation
  • Trailing closure syntax

0. Closure expression syntax

Closure expression syntax has the following general form:

{ (parameters) -> return type in
    statements
}
Copy the code

1. Create a basic closure

Simply create a variable, create a function to assign a value to a variable

let driving = {
    print("I'm driving in my car")
}
driving()
Copy the code

2. Accept arguments in closures

let driving = {(_ place: String) in 
    print("I'm going to \(place) in my car")
}
driving("BeiJing")
Copy the code

3. Return parameters in the closure

let drivingWithReturn = {(place: String) - >String in 
    return "I'm going to \(place) in my car"
}
let message = drivingWithReturn("London")
print(message)
Copy the code

4. Closures as arguments

Because closures can be used like strings and integers, they can be passed to functions. It’s a little convoluted, but you’ll get it if you write too much

func travel(action: (_: String) - >String) {
    print("I'm getting ready to go,")
    let message = action("Beijing")
    print(message)
    print("I'm arrived!")
}
travel(action: drivingWithReturn)
Copy the code

5. Trailing closure syntax

If you need to pass a long closure expression as the last argument to a function, it is useful to replace the closure with a trailing closure. A trailing closure is a closure expression written after the function parentheses that the function supports calling as the last argument. When using a trailing closure, you don’t have to write its parameter tag:

To prove this, write a travel() function that accepts the action closure argument so that it can be printed to run between two print() calls

func travel(action: () - >Void) {
    print("I'm getting ready to go.")
    action()
    print("I arrived!")}Copy the code

In fact, since there are no other arguments, we can eliminate the parentheses entirely:

travel {
    print("I'm driving in my car")}Copy the code

6. When the closure accepts arguments, use them as arguments

func travel(action: (String) - >Void) {
    print("I'm getting ready to go.")
    action("London")
    print("I arrived!")
}
travel { (place: String) in
    print("I'm going to \(place) in my car")}// Return a value with a closure as an argument
func travel(action: (String.String) - >String) {
    print("I'm getting ready to go.")
    let description = action("Beijing"."London")
    print(description)
    print("I arrived!")
}
travel{(a: String, b: String) in 
    return "I'm going to \(a) and \(b) in my car"
}

Copy the code

6. Why does Swift have trailing closure syntax?

Trailing closures make Swift code easier to read, even if it’s hard to learn,

But after understanding the feeling is still quite fragrant; Can simplify many of the OC era of complex writing

Remember when we were writing Objective-C, we used to write UIView animation functions;

[UIView animateWithDuration:1.5 animations:^{<# Code# >} Completion :^(BOOL finished) {<# Code# >}];Copy the code

Now Swift is written more concisely

UIView.animate(withDuration: 1.5, animations: {
    print("animation block")
}, completion: { (finished: Bool) in
    print("I'm getting ready to go \(finished)")})Copy the code

Animations can be omitted

UIView.animate(withDuration: 1, delay: 1, options: .curveEaseIn) {
    print("animaitons block")
} completion: { (a:Bool) in
    print("completion")}Copy the code

The meaning of the trailing closure is then appended directly to the function name