openplanning

Hướng dẫn và ví dụ Swift Closure

  1. Closure là gì?
  2. Function so với Closure
  3. Khai báo Closure nặc danh
  4. Ngầm định giá trị trả về
  5. Closure sử dụng trong hàm

1. Closure là gì?

Closure: Về mặt ngữ nghĩa là một "Bao đóng", nó gần giống với một khối lệnh trong C hoặc Object-C. Closure là một khối lệnh đặc biệt, nó có thể có 0 hoặc nhiều tham số, và có thể có kiểu trả về.
Để đơn giản bạn hãy xem một khai báo dưới đây, bạn có thể đoán được ý nghĩa của nó?
Các khai báo ở trên có thể được giải thích bởi hình minh họa dưới đây:
Đây là một cú pháp khai báo biến với kiểu dữ liệu, và gán giá trị cho biến mà bạn đã quen thuộc:
MyFirstClosure.swift
import Foundation

// Khai báo một biến myVar1, với kiểu dữ liệu, và gán giá trị cho nó. 
var myVar1 : () -> () =  { 
    print("Hello from Closure 1");
} 
// Khai báo một biến myVar2, với kiểu dữ liệu, và gán giá trị cho nó. 
var myVar2 : () -> (String)  = { () -> (String) in 
    return "Hello from Closure 2" 
} 
// Khai báo một biến myVar3, với kiểu dữ liệu, và gán giá trị cho nó.
var myVar3 : (Int, Int) -> (Int)  =  { (a : Int, b: Int) -> (Int) in 
    var c : Int =  a + b 
    return c
}  
func test_closure()     { 
    // Thực thi Closure.
    myVar1() 
    // Thực thi Closure, và nhận giá trị trả về.
    var str2 = myVar2() 
    print(str2) 
    // Thực thi closure, truyền (pass) các tham số
    // và nhận giá trị trả về.
    var c: Int =  myVar3(11, 22) 
    print(c) 
}
Closure chính là các khối lệnh, có thể có tham số, và thể có kiểu trả về:
Cú pháp của Closure:
{  (parameters) -> returntype in
     // statements
}

2. Function so với Closure

Function chính là một trường hợp đặc biệt của Closure. Function chính là một Closure có tên hoặc có thể nói Closure chính là một Function nặc danh.
Về định nghĩa:
Về cách sử dụng:

3. Khai báo Closure nặc danh

Khi khai báo Closure bạn có thể không cần viết tên của các tham số, các tham số có thể tham chiếu thông qua $0, $1,...
AnonymousClosure.swift
import Foundation

// Khai báo một Closure theo cách thông thường.
var myClosure : (String, String) -> String 
    = { (firstName: String, lastName: String) -> String in  
        return firstName + " " + lastName
} 
// Khai báo một Closure theo cách nặc danh (anonymous).
// (Bỏ qua tên các tham số).
var anonymousClosure : (String, String) -> String 
    = {
        // Sử dụng:
        // $0: Là tham số đầu tiên
        // $1: Là tham số thứ hai
        return $0 + " " + $1
}
Chú ý: $0, $1,... là các tham số nặc danh, chúng chỉ được sử dụng trong các Closure nặc danh, nếu sử dụng trong các Closure thông thường bạn sẽ nhận được một thông báo lỗi.
Anonymous closure arguments cannot be used inside a closure that has explicit arguments
Ví dụ với Closure năc danh (2):
AnonymosClosure2.swift
import Foundation 

func test_anonymousClosure()  { 
    // Khai báo một biến kiểu Closure.
    var mySum : ( Int, Int ) -> (Int)
    
    // Gán một closure nặc danh cho nó.
    // $0: Là tham số đầu tiên
    // $1: Là tham số thứ hai
    mySum =  {
        return $0 + $1
    } 
    var value = mySum(1, 2) 
    print(value) 
}

4. Ngầm định giá trị trả về

Nếu trong nội dung của Closure có duy nhất một biểu thức, bạn có thể bỏ qua từ khóa return.
ImplicitReturnValues.swift
import Foundation

// Đây là một Closure mà nội dung của nó chỉ có một biểu thức duy nhất
var closureWithReturn  =  { (a: Int, b: Int) -> Int in 
    // Một biểu thức (expression) duy nhất.
    return a + b 
} 
// Có thể bỏ qua từ khoá 'return'.
var closureWithoutReturn =  { (a: Int, b: Int) -> Int in 
    // Nếu chỉ là một biểu thức (expression) duy nhất.
    // Có thể bỏ qua từ khoá 'return'.
    a + b 
}

5. Closure sử dụng trong hàm

  • TODO