我注意到assert在Swift中编写第一个值时输入为
@autoclosure() -> Bool
用重载方法返回一个通用T值,通过它来测试存在LogicValue protocol.
但严格坚持手头的问题.它似乎想要一个@autoclosure返回一个Bool.
编写一个不带参数并返回Bool的实际闭包不起作用,它要我调用闭包使其编译,如下所示:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
然而,简单地通过Bool工作:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
那么发生了什么?什么是@autoclosure?
编辑: @auto_closure已重命名@autoclosure
edd*_*e_c 261
考虑一个带有一个参数的函数,一个不带参数的简单闭包:
func f(pred: () -> Bool) {
    if pred() {
        print("It's true")
    }
}
要调用此函数,我们必须传入一个闭包
f(pred: {2 > 1})
// "It's true"
如果我们省略大括号,我们传入一个表达式,这是一个错误:
f(pred: 2 > 1)
// error: '>' produces 'Bool', not the expected contextual result type '() -> Bool'
@autoclosure在表达式周围创建一个自动闭包.因此,当调用者编写一个类似的表达式时2 > 1,它{2 > 1}会在传递给它之前自动包装到一个闭包中f.因此,如果我们将此应用于函数f:
func f(pred: @autoclosure () -> Bool) {
    if pred() {
        print("It's true")
    }
}
f(pred: 2 > 1)
// It's true
因此它只需要一个表达式,而无需将其包装在闭包中.
mat*_*att 29
这是一个实际的例子 - 我的print覆盖(这是Swift 3):
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不会在发布模式下评估其参数.
Con*_*nor 11
来自docs的auto_closure描述:
您可以将auto_closure属性应用于参数类型为()并返回表达式类型的函数类型(请参阅类型属性).autoclosure函数捕获指定表达式的隐式闭包,而不是表达式本身.以下示例在定义非常简单的断言函数时使用auto_closure属性:
这是苹果与它一起使用的例子.
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传递给方法,因为它是一个布尔表达式,但不能传递闭包.
| 归档时间: | 
 | 
| 查看次数: | 28284 次 | 
| 最近记录: |