Swift Tips 002 - Using auto closures

每天了解一点不一样的 Swift 小知识

代码截图

小笔记

自动闭包是什么

自动闭包是一种自动创建的闭包, 用于包装传递给函数作为参数的表达式。这种闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。

这种语法让你能够省略闭包的花括号,用一个普通的表达式来代替显式的闭包。除了简化写法,还有一个需要注意的就是自动闭包所包含的代码是延迟执行的。

下面代码中的 customerProvider 就是一个自动闭包。

var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// 打印出“5”
let customerProvider = { customersInLine.remove(at: 0) }
print(customersInLine.count)
// 打印出“5”
print("Now serving \(customerProvider())!")
// Prints "Now serving Chris!"
print(customersInLine.count)
// 打印出“4”

如果想了解更多关于闭包的知识, 建议阅读 Swift Programming Language 里的相应章节: 传送门

@autoclosure 是什么东西

@autoclosure 是帮助开发者简化闭包写法的一个语法糖, 当函数的入参是一个闭包时,我们通常会这么写代码。

// customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// 打印出“Now serving Alex!”

但使用 @autoclosure 后,代码将简化成如下的形式:

// customersInLine is ["Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: @autoclosure () -> String) {
print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))
// 打印“Now serving Ewa!”

注意调用 serve 方法时,customer 的参数值不用再使用 { } 来显示声明此处是一个闭包,系统会根据 @autoclosure 自动将对应参数转化为闭包。

什么时候使用这个特性呢

简单来说, 当你设计的函数入参是一个用意明确的闭包且需要被延迟执行时, 用 @autoclosure 一个不二之选。

更详细, 更完整的观点陈述, 可以阅读国外开发者 Pavel Gnatyuk 的文章: @autoclosure what, why and when