在函数调用过程中,如果需要改变一个参数的值则需要通过引用传递或指针传递地址的方式进行,其实也是按值传递,只不过传递的是需要改变的变量地址而已,那么可不可以将被调用的函数内部局部变量的状态也可以保存起来呢?当调用这个函数时,就可以继续上次调用过程中所保留的状态,并进行恢复.这中保留函数调用上下文的方法就是”闭包”.在许多函数式编程语言尤其是带有垃圾回收特性语言中,都支持闭包功能,闭包其实就是将函数执行的上下文进行保存,当再次调用时,又将其进行恢复.由于该函数的局部状态被保留并被多次调用,这也就类似于数学中的闭包.
支持闭包特性通常需要一个嵌套函数,通过执行嵌套函数来改变所在父函数的局部变量状态,父函数保存调用上下文状态,而嵌套函数负责修改状态的改变.
下面是不同语言的闭包版本:
python 2.6 闭包功能:
点击(此处)折叠或打开
- #!/usr/bin/python
- def counter():
- x = {'x':1}
- def increment(y):
- x['x'] += y
- print x['x']
- return increment
- if __name__ == "__main__":
- counter1 = counter()
- counter2 = counter()
- counter1(1)
- counter1(2)
- counter2(5)
- counter2(7)
Lisp方言 scheme 闭包功能(来自The Scheme Programming Language):
- (define make-counter
- (lambda ()
- (let ((next 0))
- (lambda ()
- (let ((v next))
- (set! next (+ next 1))
- v)))))
- (define counter1 (make-counter))
- (define counter2 (make-counter))
C++ 0x标准(g++ 4.6)也支持闭包功能,编译选项需要指定参数-std=c++0x,代码如下:
- #include <iostream>
- #include <functional>
- using namespace std;
- std::function<void ()> counter()
- {
- int x = 0;
- return [&] () -> void { x++;cout << "x:" << x <<endl;};
- }
- int main(int argc,char *argv[])
- {
- std::function<void ()> func = counter();
- func();
- func();
- return 0;
- }
参考资料:
1.计算机程序的构造与解释
2.wiki:closure
3.C programming:
4.javascript 的闭包:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
5.The scheme Programming Language