在Swift中,程序员可用的唯一引用类型是class
。我们知道闭包是对象,因为它们存储对在父作用域中捕获的变量的引用。闭包也是引用类型according to Apple's Swift Programming Language Guide。您可以看到分配闭包不会创建捕获的环境的副本,并且不会像以下示例一样创建对现有环境的新引用:
func test1() {
var x = 42
let f = {
print(x)
}
f() // prints 42
// `g` stores a reference to `f`
let g = f
x = 24
g() // prints 24
}
在Swift编译器中实现的闭包是否具有用于实现类的类似“基础结构”?编译器内部是否存在对语言用户隐藏的代码,这些代码在暴露时可能看起来像这样?
// pseudocode
final class Closure<ArgumentType, ReturnType> {
}
typealias ArgumentType -> ReturnType = Closure<ArgumentType, ReturnType>
如果是这样,是否有单独的处理方法来抛出这样的闭包?
// pseudocode
final class ThrowingClosure<ArgumentType, ReturnType> {
}
typealias ArgumentType throws -> ReturnType = Closure<ArgumentType, ReturnType>
这里的主要问题是,我们可以将普通闭包视为抛出闭包的子类吗?因为显然,您可以将通用的闭包分配给任何需要抛出闭包类型的地方:
func test(f: () throws -> Int, g: () -> Int) {
print((try? f())!)
print((try? g())!)
}
// prints 4 and 2
test(f: { 4 }, g: { 2 })