Swift開發基礎06-閉包

Mr.陳發表於2024-07-16

Swift的閉包(Closures)是一種將功能塊和上下文整合並演示在程式碼中的一種手段。閉包可以捕獲並儲存其上下文中的變數和常量。與普遍存在於其他語言的匿名函式(如Python的lambda、JavaScript的函式表示式)類似,Swift的閉包提供了強大的功能,並在很多場景中替代了函式。

閉包有三種主要形式:

  1. 全域性函式:有名字但不捕獲任何值。
  2. 巢狀函式:有名字並能捕獲其封閉函式內的值。
  3. 閉包表示式:無名字,可以從其上下文中捕獲值。

閉包表示式語法

閉包表示式語法是構建閉包的一種方式,包含一個引數列表,一個返回型別和閉包的主體:

{ (parameters) -> returnType in
    statements
}

讓我們一步步透過示例探討一下閉包的使用情形。

示例:最基本的閉包

let simpleClosure = {
    print("Hello, Swift Closure!")
}

simpleClosure() // 輸出: "Hello, Swift Closure!"

示例:帶引數和返回值的閉包

let sumClosure = { (a: Int, b: Int) -> Int in
    return a + b
}

let result = sumClosure(3, 5)
print(result) // 輸出: 8

示例:作為引數傳遞閉包

閉包經常作為引數傳遞給函式,比如用作回撥函式。

func performOperation(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let result = performOperation(a: 10, b: 20, operation: { (x, y) -> Int in
    return x * y
})
print(result) // 輸出: 200

示例:尾隨閉包

如果閉包是函式的最後一個引數,那麼可以使用尾隨閉包的語法來書寫:

func performOperation(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let result = performOperation(a: 10, b: 20) { (x, y) -> Int in
    return x * y
}
print(result) // 輸出: 200

示例:閉包捕獲值

閉包可以捕獲並儲存其上下文中的變數值,這被稱為“捕獲”。

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    
    let incrementer: () -> Int = {
        total += incrementAmount
        return total
    }
    
    return incrementer
}

let incrementByTwo = makeIncrementer(incrementAmount: 2)

print(incrementByTwo()) // 輸出: 2
print(incrementByTwo()) // 輸出: 4

示例:自動閉包

自動閉包是一種自動捕獲表示式的閉包,多用於延時計算和副作用控制。

swift
複製程式碼
var array = [1, 2, 3]

func removeFirstElement(array: @autoclosure () -> Int?) -> Int? {
    return array()
}

let firstElement = removeFirstElement(array: array.removeFirst())
print(firstElement ?? "Array is empty") // 輸出: 1

示例:逃逸閉包(Escaping Closures)

當閉包在函式返回之後還被呼叫時,需要將其標記為@escaping

swift
複製程式碼
var completionHandlers: [() -> Void] = []

func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

someFunctionWithEscapingClosure {
    print("This is an escaping closure")
}

// 程式碼稍後執行
completionHandlers.first?() // 輸出: "This is an escaping closure"

這些示例涵蓋了Swift閉包的基礎和一些高階場景。

相關文章