为什么自动关闭延迟评估和正常关闭没有?
Why autoclosure delay evaluation and normal closure does not?
既然 Apple 声明 An autoclosure lets you delay evaluation, because the code inside isn’t run until you call the closure.,为什么自动关闭延迟评估和正常过程没有?
我借用 John Sundell 的带有自动关闭的片段来比较 with/without 自动关闭。
func assert2(_ expression: @autoclosure () -> Bool,
_ message: @autoclosure () -> String) {
guard isDebug else {
return
}
// Inside assert we can refer to expression as a normal closure
if !expression() {
assertionFailure(message())
}
}
func assert3(_ expression: () -> Bool,
_ message: () -> String) {
guard isDebug else {
return
}
// Inside assert we can refer to expression as a normal closure
if !expression() {
assertionFailure(message())
}
}
但似乎 message()
在这两种情况下都不会执行。
对我来说唯一的区别是我需要手动关闭:
override func viewDidLoad() {
super.viewDidLoad()
assert2(false, "hello2")
assert3({return false}, {return "hello3"})
}
Apple 和 John Sundell 说自动关闭延迟执行还有其他原因吗?
例如,由于 Xcode 的优化,正常闭包是否被预评估?
或者闭包以这种方式运行的任何其他原因?
如果官方文档有明确说明这一点,请提供。
我认为您误解了文档试图描绘的区别。当文档说:
An autoclosure lets you delay evaluation, because the code inside isn’t run until you call the closure.
它不是将 @autoclosure () -> Bool
("autoclosure")与 () -> Bool
("normal closure")进行比较。它正在比较 @autoclosure () -> Bool
和 Bool
.
文档假设调用者保持不变,特别是在调用者将一些表达式传递给方法的情况下。比如这样的调用代码:
assert(someBoolFunction(), someStringFunction())
使用 @autoclosure
将允许 someBookFunction
稍后成为 运行,而接受 Bool
将导致 someBoolFunction
被立即调用,甚至在调用 assert
之前。这是因为 @autoclosure
表示传递的任何表达式都通过语法糖的魔力包装到闭包中。
请注意,将函数的参数从 Bool
更改为 @autoclosure () -> Bool
通常不会对调用方造成破坏性更改(调用方仍然能够将表达式传递给函数),这就是为什么这是一个有意义的比较。
既然 Apple 声明 An autoclosure lets you delay evaluation, because the code inside isn’t run until you call the closure.,为什么自动关闭延迟评估和正常过程没有?
我借用 John Sundell 的带有自动关闭的片段来比较 with/without 自动关闭。
func assert2(_ expression: @autoclosure () -> Bool,
_ message: @autoclosure () -> String) {
guard isDebug else {
return
}
// Inside assert we can refer to expression as a normal closure
if !expression() {
assertionFailure(message())
}
}
func assert3(_ expression: () -> Bool,
_ message: () -> String) {
guard isDebug else {
return
}
// Inside assert we can refer to expression as a normal closure
if !expression() {
assertionFailure(message())
}
}
但似乎 message()
在这两种情况下都不会执行。
对我来说唯一的区别是我需要手动关闭:
override func viewDidLoad() {
super.viewDidLoad()
assert2(false, "hello2")
assert3({return false}, {return "hello3"})
}
Apple 和 John Sundell 说自动关闭延迟执行还有其他原因吗? 例如,由于 Xcode 的优化,正常闭包是否被预评估? 或者闭包以这种方式运行的任何其他原因?
如果官方文档有明确说明这一点,请提供。
我认为您误解了文档试图描绘的区别。当文档说:
An autoclosure lets you delay evaluation, because the code inside isn’t run until you call the closure.
它不是将 @autoclosure () -> Bool
("autoclosure")与 () -> Bool
("normal closure")进行比较。它正在比较 @autoclosure () -> Bool
和 Bool
.
文档假设调用者保持不变,特别是在调用者将一些表达式传递给方法的情况下。比如这样的调用代码:
assert(someBoolFunction(), someStringFunction())
使用 @autoclosure
将允许 someBookFunction
稍后成为 运行,而接受 Bool
将导致 someBoolFunction
被立即调用,甚至在调用 assert
之前。这是因为 @autoclosure
表示传递的任何表达式都通过语法糖的魔力包装到闭包中。
请注意,将函数的参数从 Bool
更改为 @autoclosure () -> Bool
通常不会对调用方造成破坏性更改(调用方仍然能够将表达式传递给函数),这就是为什么这是一个有意义的比较。