Swift - 自動閉包



閉包是一個自包含的功能塊,可以傳遞和使用在程式碼中執行任何特定任務。它可以賦值給變數或作為函式引數傳遞。它可以捕獲其周圍上下文中的值,這在處理非同步任務時非常有用。Swift 支援各種型別的閉包,例如逃逸閉包、非逃逸閉包和自動閉包。本章將詳細討論自動閉包。

Swift 中的自動閉包

Swift 支援一種特殊的閉包型別,稱為自動閉包。自動閉包會自動建立來包裝作為引數傳遞給指定函式的語句。它不接受任何引數,只在呼叫時返回其內部包裝的表示式的值。它通常用於接受閉包作為引數的函式,並允許我們將表示式的求值延遲到呼叫或需要時。

自動閉包提供了一種簡潔的語法,用於將簡單的表示式作為引數傳遞給函式,而不是建立單獨的閉包。此外,請記住不要過度使用自動閉包,因為它會使我們的程式碼難以閱讀。

宣告自動閉包

要將閉包宣告為自動閉包,我們必須使用@autoclosure關鍵字。

語法

以下是自動閉包的語法:

func functionname(_closureParameter: @autoclosure() -> ReturnType){
   // body
}

示例

Swift 簡單程式演示自動閉包。

import Foundation

// Defining a function that takes an auto-closure
func functionForAutoclosure(myClosure: @autoclosure () -> Void) {
   print("Performing Action")
   myClosure()
}

// Calling the function with a closure as an argument
functionForAutoclosure(myClosure: print("Hello! This is the auto closure"))
輸出

它將產生以下輸出:

Performing Action
Hello! This is the auto closure

示例

使用自動閉包的 Swift 程式來新增兩個數字。

// Function to find the sum of two numbers using auto-closure 
func addition(_ x: Int, _ y: Int, add: @autoclosure () -> Int) {
   let output = x + y + add()
   print("The sum of \(x) and \(y) is \(output)")
}

// Calling the function with a closure as an argument
addition(2, 4, add: 7 + 8)
輸出

它將產生以下輸出:

The sum of 2 and 4 is 21

自動閉包作為逃逸閉包

在 Swift 中,我們允許逃逸自動閉包。逃逸閉包是一種特殊的閉包,它作為引數傳遞給函式,但在函式返回後呼叫。自動閉包和逃逸閉包是不同的術語,但我們可以將它們結合起來,將表示式的求值延遲到需要時。

要將自動閉包宣告為逃逸閉包,我們必須同時使用@autoclosure@escaping關鍵字。

語法

以下是作為逃逸閉包的自動閉包的語法:

func functionName(_closureParameter: @autoclosure @escaping() -> ReturnType){
   // body
}

示例

Swift 簡單程式演示自動閉包作為逃逸閉包。

import Foundation

class AutoClosureExample {    
   var queue: [() -> Void] = []
    
   // Method that takes an auto closure as an escaping closure
   func closureToQueue(_ myClosure: @autoclosure @escaping () -> Void) {
      queue.append(myClosure)
   }
    
   // Method that executes the closures in the queue
   func runClosure() {
      for closure in queue {
         closure()
      }
   }
}

// Creating object of AutoClosureExample class
let obj = AutoClosureExample()

// Using an auto closure as an escaping closure
obj.closureToQueue(print("My Closure 1"))
obj.closureToQueue(print("My Closure 2"))

// Activating the passage of time
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

   // Execute the closures in the queue
   obj.runClosure()
}

輸出

它將產生以下輸出:

My Closure 1
My Closure 2

此程式將在 Xcode 或本地 Swift playground 上執行。它線上 Swift 編譯器上不起作用,因為線上 Swift 編譯器與執行非同步操作不相容。

廣告