In Swift, the only reference type available to a programmer is a class
. We know that closures are objects as they store references to variables captured in the parent scope. Closures are also reference types, according to Apple's Swift Programming Language Guide. You can see that assigning a closure doesn't create a copy of a captured environment and creates a new reference to the existing environment like in this example:
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
}
Are closures implemented in the Swift compiler with a similar "infrastructure" used for implementing classes? Is there a code in the compiler internals hidden from language users that could have looked like this when exposed?
// pseudocode
final class Closure<ArgumentType, ReturnType> {
}
typealias ArgumentType -> ReturnType = Closure<ArgumentType, ReturnType>
If so, is there a separate treatment for throwing closures that looks like this?
// pseudocode
final class ThrowingClosure<ArgumentType, ReturnType> {
}
typealias ArgumentType throws -> ReturnType = Closure<ArgumentType, ReturnType>
The main question here is, can we consider a common closure a subclass of a throwing closure? Because it clearly looks like you can assign a common closure to a whatever place that expects a throwing closure type:
func test(f: () throws -> Int, g: () -> Int) {
print((try? f())!)
print((try? g())!)
}
// prints 4 and 2
test(f: { 4 }, g: { 2 })