10.5 捕获上下文中的变量和常量

嵌套函数或闭包可以访问它所在上下文的变量和常量,这个过程称为捕获值(capturing value)。即便是定义这些常量和变量的原始作用域已经不存在,嵌套函数或闭包仍然可以在函数体内或闭包体内引用和修改这些值。

下面看一个示例:

  1. func makeArray() -> (String)-> [String] {
  2. var ary: [String] = [String]()
  3. func addElement(element:String) ->[String] {
  4. ary.append(element)
  5. return ary
  6. }
  7. return addElement
  8. }
  9. let f1 = makeArray()
  10. println("---f1---")
  11. println(f1("张三"))
  12. println(f1("李四"))
  13. println(f1("王五"))
  14. println("---f2---")
  15. let f2 = makeArray()
  16. println(f2("刘备"))
  17. println(f2("关羽"))
  18. println(f2("张飞"))

在上述代码中,第①行定义函数makeArray,它的返回值是(String)->String[]函数类型。第②行声明并初始化了数组变量ary,它的作用域是makeArray函数体。第③行代码定义了嵌套函数addElement,在它的函数体内,第④行代码改变变量ary值,ary变量相对于函数addElement而言,是上下文中的变量。第⑤行代码是从函数体中返回变量ary。第⑥行代码是返回函数类型调用addElement

这样当在第⑦行调用的时候,f1是嵌套函数addElement的一个实例。需要注意的是,f1每次调用的时候,变量ary值都能够被保持。第⑧行代码f2也是嵌套函数addElement的一个实例。运行结果如下:

  1. ---f1---
  2. [张三]
  3. [张三, 李四]
  4. [张三, 李四, 王五]
  5. ---f2---
  6. [刘备]
  7. [刘备, 关羽]
  8. [刘备, 关羽, 张飞]

f1f2是嵌套函数addElement的不同实例,它们的运行结果也是独立的。