Ios 为什么Swift全局函数作为闭包捕获全局变量的特例?
根据:全局函数是具有名称且不捕获任何值的闭包。但我在《IOS 11编程基础知识与Swift》一书中遇到了一个使用闭包的例子,它将一个全局函数a作为参数传递给另一个全局函数B,以修改全局变量x的值。这本书指出A捕获了X,这与Swift文档中的说法相矛盾 代码示例:Ios 为什么Swift全局函数作为闭包捕获全局变量的特例?,ios,swift,closures,Ios,Swift,Closures,根据:全局函数是具有名称且不捕获任何值的闭包。但我在《IOS 11编程基础知识与Swift》一书中遇到了一个使用闭包的例子,它将一个全局函数a作为参数传递给另一个全局函数B,以修改全局变量x的值。这本书指出A捕获了X,这与Swift文档中的说法相矛盾 代码示例: func pass100(_ f: (Int) -> ()) { f(100) } var x = 0 print(x) // output 0 func setX(newX: Int) { x = newX
func pass100(_ f: (Int) -> ()) {
f(100)
}
var x = 0
print(x) // output 0
func setX(newX: Int) {
x = newX
}
pass100(setX)
print(x) //output 100
上面的代码片段在Xcode中工作,我感到困惑。有人能解释一下这里发生了什么吗?是“捕获”的意思:
闭包可以从定义它的周围上下文中捕获常量和变量。然后,闭包可以从其主体中引用和修改这些常量和变量的值,即使定义常量和变量的原始范围不再存在。
全局函数被称为不捕获任何内容,因为在程序运行时,您永远不能离开全局范围,因此捕获任何内容都没有意义。如果它确实捕获了一些东西,这意味着即使在您以某种方式“离开”了全局范围(可能程序完成了运行)之后,全局变量仍然可以更改,这将很奇怪
代码中的全局函数没有捕获任何内容。它可以更改x
的值,因为x
仍在范围内。您还没有离开全局范围
闭包可以从周围环境中捕获常量和变量
定义它的上下文
与局部一样,全局也是一个上下文A
是一个全局函数,X
是一个全局变量;因此,A
捕获X
。从技术上讲,应用程序中的所有方法都会捕获X
,因为它是在全局上下文中公开的。然而,按照惯例,“捕获”通常指的是局部范围
为了演示这一点,如果将A
和X
移动到本地范围,例如类中的方法,则不会发生任何更改-A
仍然捕获X
。您在示例中所做的一切都是将它们放在一个全局范围内,因为它们位于同一范围(或上下文)中,所以捕获规则没有改变
这是一个语义和惯例的问题,我认为这是Swift文档可能有点误导的一个领域(如果我是苹果,我会改写它)。将函数从局部范围移动到全局范围不会改变其捕获能力。我认为苹果的意思是,默认情况下,本地方法总是捕获某些东西(即使它是self
),而如果周围没有任何东西需要捕获,则不能保证全局函数捕获任何东西