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 编译器与执行异步操作不兼容。

广告