全局函数是具有名称且不捕获任何值的闭包。
在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
问题:
我相信我并不完全理解以下概念:
在操场上简单定义一个函数(比如 addOne() - > Int 这里)可能并不意味着它是一个全局函数
对于这种情况对“捕获”的错误理解,这根本不是捕获,(但为什么?)
帮助我寻找:
我非常感谢你能指出我错误理解哪一部分,甚至可以给你一些解释。
谢谢
PS:
这个问题可能是this one的重复,但是,我仍然发布它,因为它还没有干净的答案,我的问题进一步推动了这个问题。但是,如果你仍想关闭它,我尊重它,我愿意向你学习。
答案 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
的值。