Swift中auto和escaping闭包的区别和目的是什么?

时间:2017-08-13 08:40:00

标签: swift closures

我正在寻找swift中autoclosure和转义闭包的一些区别/目的。我知道一个转义闭包是我们想要在函数返回后执行的东西,但我没有得到autoclosure的概念。

2 个答案:

答案 0 :(得分:6)

  

我没有得到autoclosure闭包的概念。

autoclosure 允许函数将表达式包装在一个闭包中,以便以后执行或根本不执行。

使用 autoclosure 的一个很好的例子是||发生的short-circuit行为。

考虑这个例子:

func willCrash() -> Bool {
    fatalError()
    return true
}

let good = true

if good || willCrash() {
    print("made it")
}

输出:

made it

||运算符使用短路评估:首先计算左侧(lhs),仅当lhs计算为false时才评估右侧(rhs)。

那么,如何实施?好吧,||只是一个函数,它接受两个参数,每个参数都评估为Bool,而||将它们组合起来以返回Bool。但是在Swift中函数的正常调用方案中,在调用函数之前计算参数。如果||以明显的方式实施:

func ||(lhs: Bool, rhs: Bool) -> Bool {
    return lhs ? true : rhs
}

由于在willCrash()被调用之前执行||,它会崩溃。因此||使用 autoclosure 将第二个语句包装在闭包中,以便它可以延迟评估,直到它在{{ 1}}功能。如果第一个语句(在调用||之前评估)为||,则true的结果为||结束为没有被调用,因此避免了这个例子中的崩溃。

以下是true的定义:

||
     

描述对两个Bool值执行逻辑OR运算。逻辑OR运算符(||)组合两个Bool值并返回true   如果至少有一个值为真。如果两个值都为假,则   运算符返回false。

     

此操作员使用短路评估:   首先评估左侧(lhs)和右侧   仅当lhs评估为false时才会计算(rhs)。

忽略抛出/重新抛出这是另一个主题,static func ||(lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows -> Bool 的实现变为:

||

func ||(lhs: Bool, rhs: @autoclosure () -> Bool) -> Bool { return lhs ? true : rhs() } 仅在rhs()时调用。

答案 1 :(得分:3)

文档已经完整描述(带有示例),但如果您有任何其他问题,请问我

  

Escaping Closures

     

当闭包被传递时,闭包被称为转义函数   函数的参数,但在函数返回后调用。   当你声明一个将闭包作为其中一个的函数时   参数,你可以在参数的类型之前写@escaping   表明关闭是允许逃脱的。

  

Autoclosures

     

autoclosure是一个自动创建的封装,用于封装   表达式作为参数传递给函数。它   不接受任何参数,当它被调用时,它返回值   包含在其中的表达式。这句法   方便让你省略函数参数的大括号   写一个正常的表达式而不是一个显式的闭包。