How To Simply Use Swift Closures

1. The Definition Of Swift Closures.

Closures are described in the Swift development documentation as functional independent modules that can be passed and referenced in your code. Closures in Swift are similar to blocks in C and Objective-C, as well as anonymous functions in other programming languages. Closures are primarily designed to capture and store references to any constants and variables defined in their context, and to handle all memory management operations for you.

1.1 Swift Closures Expression Syntax.

The closure expression syntax has the following general form.

{ (input_parameters) -> (return type) in
        
     execute_code_statement
}

Closures are typed according to your needs, and the types definition of closures are typically as follows.

( input_parameters ) -> (return type)

1.2 Using typealias To Define Aliases For Closure Types.

typealias is a keyword used in Swift to redefine existing types ( similar to typedef in Object C ), new type name is used to replace previous type, and make the code clearer, simpler and easier to understand. The use of typealias is simple, just use the = operator to assign new type name and original type.

typealias <type name> = <type expression>

In this way we can use typealias to define aliases for seemingly complex closure types, so that we can use aliases to directly declare closures of such types later, below are some examples. Please note whether a closure accepts parameters, accept how many parameters, and returns what kind of values depends entirely on your requirements.

  1. Alias closure types that have no parameters and no return values as Nothing.
    typealias Nothing = () -> ()
  2. If the closure does not return a value, we can also write it like this.
    typealias Anything = () -> Void
  3. Define an alias for a closure type that accepts an Int type argument and do not return value, the alias name is PrintNumber.
    typealias PrintNumber = (Int) -> ()
  4. Define an alias for a closure type that take two Int type parameters and return an Int type value, the alias name is Add.
    typealias Add = (Int, Int) -> (Int)

2. Swift Closure Creation, Assignment And Invocation.

Closure expression can use constant form parameters, variable form parameters and input-output form parameters, but it can not provide default values. Variable form parameters need to be used at the end of the parameter list. Tuples can also be used as parameters and return types.

Keyword in is used in a closure. in can be seen as a separator. It separates the closure type declaration from the closure’s function body. in is preceded by the return type of closure and in is followed by the code that needs to be executed when a specific closure is called.

Here is a summary of several possible forms of closure creation, assignment, and invocation. Examples are as follows.

  1. Create the most complete closure using typealias.
    // Define alias Add to closure type (_ num1: Int, _ num2: Int) -> (Int)
    typealias Add = (_ num1: Int, _ num2: Int) -> (Int)
    
    // Create a constant variable of Add closure type. The constant variable name is adCloser1.
    let addCloser1: Add
    
    // Assign closure body to above constant variable addCloser1.
    addCloser1 = {
        
          (_ num1: Int, _ num2: Int) -> (Int) in
            
          return num1 + num2
    }
    
    // Invoke above Add closure constant variable and get result. 
    let result = addCloser1(20, 10)
  2. Merge closure type declaration and closure variable body code creation.
    // Define a constant variable as swift closure type.
    let addCloser1: (_ num1: Int, _ num2: Int) -> (Int)
    
    // Assign closure body execution code to above constant variable addCloser1.
    addCloser1 = {
          
       (_ num1: Int, _ num2: Int) -> (Int) in
    
       return num1 + num2
    }
    
    // Invoke above closure variable and get result.
    let result = addCloser1(20, 10)
  3. Omit closure’s parameter type and return value type in closure body.
    // Create a constant closure type variable addCloser1.
    let addCloser1: (Int, Int) -> (Int)
    
    // Assign closure body code to above closure variable.
    addCloser1 = {
             // Here we omit the parameter type and return value type.
             (num1, num2) in
    
             return num1 + num2
    }
    
    let result = addCloser1(20, 10)
  4. Combine closure type variable declaration and body code assignment.
    // Declare a closure type constant variable and assign it's body code at same time.
    
    let addCloser1: (Int, Int) -> (Int) = {
    
          (num1, num2) in
    
          return num1 + num2
    }    
    
    let result = addCloser1(20, 10)
  5. If the closure does not receive any parameter then you can omit keyword in.
    // Define a constant closure type variable and assign it's body code. The closure do not has parameters.
    let addCloser1: () -> (String) = {
                
         return "Helo World."
             
    }
    
    let result = addCloser1()
  6. Use place holder $0, $1 etc to reference parameter if parameter do not has name only has type.
    // Below closure declaration's parameter do not provide name, only provide type. 
    let addCloser1: (String, String) -> (String) = {
     
           // So we can use $0, $1 to reference parameters.
                
           return "\($0),\($1)"
    }
    
    let result = addCloser1("Hello", "World")

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.