10.5 捕获上下文中的变量和常量
嵌套函数或闭包可以访问它所在上下文的变量和常量,这个过程称为捕获值(capturing value)。即便是定义这些常量和变量的原始作用域已经不存在,嵌套函数或闭包仍然可以在函数体内或闭包体内引用和修改这些值。
下面看一个示例:
func makeArray() -> (String)-> [String] { ①
var ary: [String] = [String]() ②
func addElement(element:String) ->[String] { ③
ary.append(element) ④
return ary ⑤
}
return addElement ⑥
}
let f1 = makeArray() ⑦
println("---f1---")
println(f1("张三"))
println(f1("李四"))
println(f1("王五"))
println("---f2---") ⑧
let f2 = makeArray()
println(f2("刘备"))
println(f2("关羽"))
println(f2("张飞"))
在上述代码中,第①行定义函数makeArray
,它的返回值是(String)->String[]
函数类型。第②行声明并初始化了数组变量ary
,它的作用域是makeArray
函数体。第③行代码定义了嵌套函数addElement
,在它的函数体内,第④行代码改变变量ary
值,ary
变量相对于函数addElement
而言,是上下文中的变量。第⑤行代码是从函数体中返回变量ary
。第⑥行代码是返回函数类型调用addElement
。
这样当在第⑦行调用的时候,f1
是嵌套函数addElement
的一个实例。需要注意的是,f1
每次调用的时候,变量ary
值都能够被保持。第⑧行代码f2
也是嵌套函数addElement
的一个实例。运行结果如下:
---f1---
[张三]
[张三, 李四]
[张三, 李四, 王五]
---f2---
[刘备]
[刘备, 关羽]
[刘备, 关羽, 张飞]
f1
与f2
是嵌套函数addElement
的不同实例,它们的运行结果也是独立的。