首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用Swift @autoclosure

如何使用Swift @autoclosure
EN

Stack Overflow用户
提问于 2014-06-08 11:05:30
回答 6查看 30.9K关注 0票数 152

我注意到在Swift中编写assert时,第一个值的类型为

代码语言:javascript
复制
@autoclosure() -> Bool

使用重载方法返回泛型T值,通过LogicValue protocol测试是否存在。

然而,严格地坚持手头的问题。它似乎需要一个返回Bool@autoclosure

编写一个不带参数并返回布尔值的实际闭包是不起作用的,它希望我调用闭包来编译它,如下所示:

代码语言:javascript
复制
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)

然而,简单地传递一个布尔值是有效的:

代码语言:javascript
复制
assert(false, "No user has been set", file: __FILE__, line: __LINE__)

那么到底是怎么回事呢?什么是@autoclosure

编辑: @auto_closure已重命名为@autoclosure

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2014-06-08 13:28:48

考虑一个带有一个参数的函数,一个不带参数的简单闭包:

代码语言:javascript
复制
func f(pred: () -> Bool) {
    if pred() {
        print("It's true")
    }
}

要调用此函数,我们必须传入一个闭包

代码语言:javascript
复制
f(pred: {2 > 1})
// "It's true"

如果我们省略了大括号,我们将传入一个表达式,这是一个错误:

代码语言:javascript
复制
f(pred: 2 > 1)
// error: '>' produces 'Bool', not the expected contextual result type '() -> Bool'

@autoclosure在表达式周围创建一个自动闭合。因此,当调用者编写像2 > 1这样的表达式时,在传递给f之前,它会自动包装到闭包中成为{2 > 1}。因此,如果我们将此应用于函数f

代码语言:javascript
复制
func f(pred: @autoclosure () -> Bool) {
    if pred() {
        print("It's true")
    }
}

f(pred: 2 > 1)
// It's true

因此,它只使用一个表达式,而不需要将其包装在闭包中。

票数 276
EN

Stack Overflow用户

发布于 2016-07-13 01:50:39

这里有一个实际的例子-我的print覆盖(这是Swift 3):

代码语言:javascript
复制
func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    Swift.print(item(), separator:separator, terminator: terminator)
    #endif
}

当你说print(myExpensiveFunction())时,我的print覆盖覆盖了Swift的print,并被调用。因此,myExpensiveFunction()被包装在一个闭包中,并且不进行求值。如果我们处于发布模式,它将永远不会被计算,因为item()将不会被调用。因此,我们有一个版本的print,它在发布模式下不计算其参数。

票数 31
EN

Stack Overflow用户

发布于 2014-06-08 11:47:50

文档中对auto_closure的描述:

您可以将auto_closure属性应用于参数类型为()并返回表达式类型的函数类型(请参见类型属性)。自动闭包函数捕获指定表达式上的隐式闭包,而不是表达式本身。下面的示例在定义一个非常简单的assert函数时使用auto_closure属性:

下面是苹果使用的例子。

代码语言:javascript
复制
func simpleAssert(condition: @auto_closure () -> Bool, message: String) {
    if !condition() {
        println(message)
    }
}
let testNumber = 5
simpleAssert(testNumber % 2 == 0, "testNumber isn't an even number.")

基本上,它的意思是你传递一个布尔表达式作为第一个参数,而不是闭包,它会自动为你创建一个闭包。这就是为什么您可以将false传递给该方法,因为它是一个布尔表达式,但不能传递闭包。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24102617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档