Why does the compiler treat closures and local functions differently?
I thought closures and functions are the same thing. But when referencing a property inside the local compiler, the function doesn't need self. But inner closure requires writing yourself. I mean, why are these two things different?
Sample code for clarity:
class Foo {
let bar = "bar"
func baz() {
func localBaz() {
println(bar) // No complain from compiler.
}
let bazClosure = {
println(self.bar) // Here if I write just println(bar), compiler complains.
}
}
}
source to share
You're wrong - functions and closures in Swift are not the same thing. A func
essentially sets up the binding lazy var
with the declaration [unowned self]
. Thus, if you want to get rid of func
, you can convert the following:
class Foo {
let bar = "bar"
// this is not your 'baz'; just an example
func baz () { println (bar) }
}
}
and
class Foo {
let bar = "bar"
lazy var baz = { [unowned self] in println (self.bar) }
}
You can see that it func
does more than just close.
Additionally, and importantly, it func
sets up a recursive binding framework that allows the body func bar
to reference bar
. Thus, you can write:
1> class Foo {
2. func fact (x:Int) -> Int {
3. if 1 == x { return x }
4. else { return x * fact (x - 1) }}
5. }
6> Foo().fact(5)
$R0: (Int) = 120
but not
7> class Foo {
8. lazy var fact = { (x:Int) -> Int in
9. if 1 == x { return x }
10. else { return x * fact (x - 1) }}}
repl.swift:10:27: error: variable used within its own initial value
else { return x * fact (x - 1) }}}
^
source to share
In fact, I don't know why I closure
need to quickly access the properties of an instance, but think about it.
Yours baz()
is a function of a class, I mean that it belongs to a class Foo
and closure
as an external function. In Objective-C, all of the functions in a class really need an argument self
to call that function.
So a closure
needs a self
pointer (or something named self
to refer to an instance Foo
) to access its property.
source to share