2016-09-28 51 views
0

全局函数是具有名称并且不捕获任何值的闭包。为什么这不算作封闭捕获?

在swift中,函数是闭包的空间形式。不同的是函数有一个名称,如果它是一个全局函数,它不能从周围的上下文中捕获常量和变量。

然而,我发现,全球功能还可以捕获从周围的背景下也将常量和变量(请参阅下面的示例代码)

let referenceInt = 10 

func addOne() -> Int { 
     return referenceInt + 1 //captured the constant referenceInt 
} 

let fooA = addOne 
let fooB = addOne 
let fooC = addOne 

print(fooA()) //prints 11 
print(fooB()) //prints 11 
print(fooC()) //prints 11, (func addOne captured referenceInt ?) 

print(referenceInt) //prints 10 

问题:

我相信我并没有完全理解以下概念:

  1. 只需在操场上定义一个函数(如addOne() - >诠释这里)可能不意味着它是一个全球性的功能

  2. 具有“捕捉”这种情况下错误的认识,这是不是一个捕获所有,(但是为什么)

帮助我在寻找:

我会很感激你能指出我错误地理解其中一部分,会更伟大的,你可以给我一些解释。

感谢

PS:

这个问题可能是this one重复,但是,我还是将它张贴因为没有它没有干净的答案了,我的问题,推动问题的远一点。但是,如果您仍然想要关闭它,我尊重这一点,我愿意向您学习。

回答

1

首先,我会质疑你的前提。封闭是封闭。 Swift中的所有函数都是闭包,它们都以相同的方式捕获。

其次,我没有看到你的代码与捕获或关闭有什么关系。你在代码中没有做任何事情来测试是否有任何东西被捕获。 let fooA = addOne类型的赋值没有做任何有趣的事情,addOne中的代码也没有做任何有趣的事情。您只是在代码运行时添加两个值。当然addOne内的代码被允许为参考到全局变量referenceInt,但这仅仅是因为它在范围内。你在这里没有做任何事情,引发了关闭的特殊权力。

这是你的代码的修正版,它显示捕获的行动:

struct Test { 
    var referenceInt = 10 

    func addOne() -> Int { 
     return referenceInt + 1 // capture 
    } 

    mutating func test() { 
     let fooA = self.addOne 
     let fooB = self.addOne 
     let fooC = self.addOne 

     referenceInt = 100 // :) 

     print(fooA()) //prints 11 
     print(fooB()) //prints 11 
     print(fooC()) //prints 11 

     print(referenceInt) //prints 100 
    } 

} 

var t = Test() 
t.test() 

我们调用fooA等前更改referenceInt。拨打fooA仍然给出11,因为self.referenceInt的值被捕获之前我们更改了referenceInt

+0

也许它会帮助你阅读我的书,如果你想看看为什么闭包很有趣,捕捉真正需要什么:从这里开始:http://www.apeth.com/swiftBook/ch02.html#_closures – matt

+0

亲爱的马特,我想你指出了我的问题。是的,我有感觉,我没有完全理解封闭,它不是封闭。我会很高兴看到你的书。非常感谢您的帮助 – SLN

+1

我添加了对代码的修改,使您可以看到捕获的实际情况。我认为这也证实了你的另一个直觉,那就是操场不是测试这类事情的非常有用的地方。 – matt

相关问题