为啥自动关闭延迟评估和正常关闭不?
Posted
技术标签:
【中文标题】为啥自动关闭延迟评估和正常关闭不?【英文标题】:Why autoclosure delay evaluation and normal closure does not?为什么自动关闭延迟评估和正常关闭不? 【发布时间】:2020-06-19 03:36:01 【问题描述】:既然Apple声明An autoclosure lets you delay evaluation, because the code inside isn’t run until you call the closure.,为什么自动关闭延迟评估和正常课程没有?
我从 John Sundell 借用了带有自动关闭的 sn-p 来比较有/没有自动关闭。
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 的优化而对正常闭包进行了预评估? 或者闭包以这种方式表现的任何其他原因?
如果有明确说明这一点的,请提供官方文件。
【问题讨论】:
您似乎在询问“正常关闭”,但您显示的代码 sn-p 显示了自动关闭。你到底在问什么? 感谢您的评论。是为了比较。我又编辑了一遍,希望现在够清楚了。 【参考方案1】:我认为您误解了文档试图绘制的区别。当文档说:
自动闭包可以让您延迟评估,因为内部的代码在您调用闭包之前不会运行。
这不是将@autoclosure () -> Bool
(“自动关闭”)与() -> Bool
(“正常关闭”)进行比较。它将@autoclosure () -> Bool
与Bool
进行比较。
文档假设调用者保持不变,特别是在调用者将一些表达式传递给方法的情况下。例如,对于这样的调用代码:
assert(someBoolFunction(), someStringFunction())
使用@autoclosure
将允许someBookFunction
稍后运行(或根本不运行),而接受Bool
将导致立即调用someBoolFunction
,甚至在调用assert
之前。这是因为@autoclosure
表明传递的任何表达式都通过语法糖的魔法包装到一个闭包中。
请注意,将函数的参数从Bool
更改为@autoclosure () -> Bool
通常不会对调用者造成重大更改(调用者仍然能够将表达式传递给函数),这就是为什么这是一个有意义的比较。
【讨论】:
吹毛求疵,但它是在某些极端情况下的突破性变化。例如,bools.reduce(true, &&)
不会工作,因为 func &&(...)
中的自动关闭功能,但如果它没有自动关闭功能,就像 ints.reduce(0, +)
一样,它会工作。
@NewDev 哇,我从来没有写过reduce(true, &&)
,而是一直使用allSatisfy
...直到现在才知道这是一个错误。
哈哈.. 这只是一个说明性的例子 :) 不一定有用。我很惊讶这也是一个错误
很好的例子!我认为它解释了苹果文件的想法。感谢您的清晰解释。以上是关于为啥自动关闭延迟评估和正常关闭不?的主要内容,如果未能解决你的问题,请参考以下文章