我从来没有真正理解何时使用@escaping。我理解它的作用(即转义闭包和非转义闭包之间的区别),但tbf我一直依赖Xcode来告诉我何时将修饰符添加到我的参数中。
我的问题是,为什么这种情况@escaping只适用于非零闭包?这就是我的意思:
func someFunc(someArg: Int, callback: @escaping (Error?) -> Void) {
DispatchQueue.global(qos: .background).async {
...
}
}
Run Code Online (Sandbox Code Playgroud)
在上面,如果我不添加@escapingXcode 会给我一个错误。但是,如果我callback像下面这样设置可选,则将结果保留 @escaping在 Xcode 错误中:
// This is wrong (Xcode complains about @escaping)
func someFunc(someArg: Int, callback: @escaping ((Error?) -> Void)?) {
DispatchQueue.global(qos: .background).async {
...
}
}
Run Code Online (Sandbox Code Playgroud)
这是为什么?谢谢你!
如您所知,默认情况下,闭包参数无法转义。你必须添加@escaping才能让他们逃脱。请参阅此处了解闭包逃逸的含义。
更准确的措辞是,函数参数位置中的闭包默认情况下是非转义的。如您所知,((Error?) -> Void)?是 的语法糖Optional<(Error?) -> Void>。这里,闭包类型不在“函数参数位置”。它用作泛型类型的泛型参数Optional。这只是我的意见,但您不认为似乎将可选@escaping Optional<(Error?) -> Void> 标记为“转义”吗?
对于更极端的情况,元组怎么样?如何仅将一对闭包中的第一项标记为转义?另外,如果我有一个T<(Error?) -> Void>,是否保证它一定会存储闭包的实例?我的意思是,它只是一个通用类型:
class Foo<T> {}
let a: Foo<(Int) -> Int> = Foo()
Run Code Online (Sandbox Code Playgroud)
@escaping那么应该对这个结构做什么呢?
最后,包裹在一个Optional 已经逃逸的闭包中不是吗Optional?
也许是因为需要设计、实现和测试的东西太多,Swift 团队只是在可选值和元组中进行了所有闭包,以及隐式转义的其他泛型类型。
另请参阅:SR-2444
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |