为什么这不算作封闭捕获?

时间:2016-09-28 14:22:48

标签: swift function closures

  

全局函数是具有名称且不捕获任何值的闭包。

在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() - > Int 这里)可能并不意味着它是一个全局函数

  2. 对于这种情况对“捕获”的错误理解,这根本不是捕获,(但为什么?)

  3. 帮助我寻找:

    我非常感谢你能指出我错误理解哪一部分,甚至可以给你一些解释。

    谢谢

    PS:

    这个问题可能是this one的重复,但是,我仍然发布它,因为它还没有干净的答案,我的问题进一步推动了这个问题。但是,如果你仍想关闭它,我尊重它,我愿意向你学习。

1 个答案:

答案 0 :(得分: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()

我们在调用referenceInt之前更改 fooA,依此类推。调用fooA仍然会给出11,因为在我们更改self.referenceInt 之前已捕获了referenceInt的值。