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.
        }
    }
}

      

+3


source to share


2 answers


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) }}}

                      ^

      

+2


source


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.

0


source







All Articles