Closure (闭包)


Overview

  闭包(Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包通常应用在“fisrt-class function”特性的编程语言中。

  闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

  闭包的概念出现于60年代,最早实现闭包的程序语言是Scheme。之后,闭包被广泛使用于函数式编程语言如ML语言和LISP。很多命令式程序语言也开始支持闭包。

  在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。运行时,一旦外部的 函数被执行, 一个闭包就形成了,闭包中包含了内部函数的代码,以及所需外部函数中的变量的引用。其中所引用的变量称作上值(upvalue)。

闭包的用途

  • 状态表达。闭包可以用来完成信息隐藏,并进而应用于需要状态表达的某些编程范型中。

  • 定义自己的控制结构. 因为闭包只有在被调用时才执行操作(暂且不论用于生成这个闭包对象本身的开销,比如 C++ 中按值捕获意味着执行复制构造函数),即“惰性求值”,所以它可以被用来定义控制结构。例如:在Smalltalk语言中,所有的控制结构,包括分歧条件(if/then/else)和循环(while和for),都是通过闭包实现的。用户也可以使用闭包定义自己的控制结构。

  • 多个函数可以使用一个相同的环境,这使得它们可以通过改变那个环境相互交流。

  • 闭包可以用来实现对象系统。

闭包的实现原理

  典型实现方式是定义一个特殊的数据结构,保存了函数地址指针与闭包创建时的函数的词法环境表示(那些非局部变量的绑定)。

语言案例

JavaScript例子:

function derivative(f,  dx) {
  var pie = 3.141516;
  return  function (x) {
    return (f(x + dx) - f(x)) / dx + pie;
  };
}

var closure_1 = derivative((num)=>{return num;}, 2);

closure_1(1);//4.141516

语言支持


References

1. Closure (computer programming))



results matching ""

    No results matching ""