为什么编译器以不同方式处理闭包和本地函数?

时间:2014-12-15 02:09:38

标签: function swift closures

我认为闭包和功能是一回事。但是当引用本地函数编译器内的属性时,不需要self。但内部封闭需要自我写作。我的意思是为什么这两件事情有所不同?

为清晰起见,示例代码:

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

2 个答案:

答案 0 :(得分:2)

你的期望是错误的 - Swift中的函数和闭包不是一回事。 func基本上会设置lazy var绑定[unowned self]声明。因此,如果你想摆脱func,你可以改变以下内容:

class Foo {
  let bar = "bar"
  // this is not your 'baz'; just an example
  func baz () { println (bar) }
  }
}

作为

class Foo {
  let bar = "bar"
  lazy var baz = { [unowned self] in println (self.bar) }
}

你可以看到func做的不仅仅是关闭。

此外,重要的是,func设置了一个递归绑定环境,允许func bar的主体引用bar。因此你可以写:

  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

但不是

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

                      ^

答案 1 :(得分:0)

确实,我不知道为什么closure需要swift来访问实例属性,但让我们考虑一下。

您的baz()是一个类函数,我的意思是它属于类Fooclosure就像一个外部函数。在Objective-C中,所有类函数实际上都需要一个self参数来调用该函数。

因此,closure需要self指针(或名为self的内容引用Foo的实例)才能访问其属性。