我注意到在Swift中编写assert
时,第一个值的类型为
@autoclosure() -> Bool
使用重载方法返回泛型T
值,通过LogicValue
protocol
测试是否存在。
然而,严格地坚持手头的问题。它似乎需要一个返回Bool
的@autoclosure
。
编写一个不带参数并返回布尔值的实际闭包是不起作用的,它希望我调用闭包来编译它,如下所示:
assert({() -> Bool in return false}(), "No user has been set", file: __FILE__, line: __LINE__)
然而,简单地传递一个布尔值是有效的:
assert(false, "No user has been set", file: __FILE__, line: __LINE__)
那么到底是怎么回事呢?什么是@autoclosure
编辑: @auto_closure
已重命名为@autoclosure
发布于 2014-06-08 13:28:48
考虑一个带有一个参数的函数,一个不带参数的简单闭包:
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
这样的表达式时,在传递给f
之前,它会自动包装到闭包中成为{2 > 1}
。因此,如果我们将此应用于函数f
func f(pred: @autoclosure () -> Bool) {
if pred() {
print("It's true")
}
}
f(pred: 2 > 1)
// It's true
因此,它只使用一个表达式,而不需要将其包装在闭包中。
发布于 2016-07-13 01:50:39
这里有一个实际的例子-我的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
,它在发布模式下不计算其参数。
发布于 2014-06-08 11:47:50
文档中对auto_closure的描述:
您可以将auto_closure属性应用于参数类型为()并返回表达式类型的函数类型(请参见类型属性)。自动闭包函数捕获指定表达式上的隐式闭包,而不是表达式本身。下面的示例在定义一个非常简单的assert函数时使用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传递给该方法,因为它是一个布尔表达式,但不能传递闭包。
https://stackoverflow.com/questions/24102617
复制相似问题