swift学习资集

Swift 自动闭包(autoclosure)

2021-09-27  本文已影响0人  sampson6688

自动闭包

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”

在闭包的代码中,customersInLine 的第一个元素被移除了,不过在闭包被调用之前,这个元素是不会被移除的。
如果这个闭包永远不被调用,那么在闭包里面的表达式将永远不会执行,那意味着列表中的元素永远不会被移除。

注意:
1. 注意,customerProvider 的类型不是 String,而是 () -> String。
2. 一个没有参数且返回值为 String 的函数。

//  serve(customer:) 函数接受一个返回顾客名字的显式的闭包。
func serve(customer customerProvider: () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: { customersInLine.remove(at: 0) } )
// 打印出“Now serving Alex!”
func serve(customer customerProvider: @autoclosure () -> String) {
    print("Now serving \(customerProvider())!")
}
serve(customer: customersInLine.remove(at: 0))

注意:
1. 过度使用 autoclosures 会让你的代码变得难以理解。
2. 上下文和函数名应该能够清晰地表明求值是被延迟执行的。

如果你想让一个自动闭包可以“逃逸”,则应该同时使用 @autoclosure 和 @escaping 属性。

// customersInLine i= ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
    customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))
 
print("Collected \(customerProviders.count) closures.") // 打印“Collected 2 closures.”
for customerProvider in customerProviders {
    print("Now serving \(customerProvider())!")
}
// 打印“Now serving Barry!”
// 打印“Now serving Daniella!”

collectCustomerProviders(_ : ) 函数并没有调用传入的 customerProvider 闭包,而是将闭包追加到了 customerProviders 数组中。
这个数组定义在函数作用域范围外,这意味着数组内的闭包能够在函数返回之后被调用。
因此,customerProvider 参数必须允许“逃逸”出函数作用域。

上一篇 下一篇

猜你喜欢

热点阅读