闭包(closure)=函数+环境,函数闭锁于词法环境中称“闭包”。
利用Common Lisp闭包特性,在函数内部可以直接引用函数所处词法环境中的变量,如:
(defun make-adder (n) #'(lambda (x) (+ x n)))
Lambda表达式内部使用所处词法环境中的n,这就创建了闭包。Common Lisp中函数是“一等公民”,这里是作为返回值;将一个函数作为另一个函数的参数也是非常常见的用法
此处n的生命周期已经不限于make-adder的调用与返回之间,而是作为闭包的一部分,与内部这个lambda表达式的生命周期同样长,即使make-adder已经返回,调用这个返回的lambda表达式时,仍可获取到当时传入的那个n
我曾疑惑:这和C语言的static变量有什么区别呢?那区别是非常大的:如果多次调用make-adder,每一次传入不同的n,返回的每一个函数实例均会记住对应的n,而不像static变量那样是共享的一个全局变量
从某种程度上来说,闭包很像是一个对象,对变量与函数进行了封装,并且具有实例化能力;C++中的Lambda表达式也是用函数对象来实现的,充分吸收了闭包的大部分特点
越学越觉得函数式编程不可思议,我建议所有人都去学函数式编程(