在第一个示例中,结果函数中没有变量n
,它只是(lambda (x) (+ 3 x))
。它不需要词法绑定,因为lambda中没有可用变量,即没有变量需要保留在闭包的绑定中。如果你不需要变量n
可用,作为变量在函数的使用中,即如果它在函数定义时间(= 3)的值是你所需要的,那么第一个例子就是你所需要的。
(fset 'ad1 (make-adder1 3))
(symbol-function 'ad1)
回报:
(lambda (x) (+ 3 x))
第二个示例创建的是,实际上,创建并应用复杂的闭合功能。
(fset 'ad2 (make-adder2 3))
(symbol-function 'ad2)
回报
(lambda (&rest --cl-rest--)
(apply (quote (closure ((--cl-n-- . --n--) (n . 3) t)
(G69710 x)
(+ (symbol-value G69710) x)))
(quote --n--)
--cl-rest--))
第三种选择是使用lexical-binding
文件局部变量并使用最简单的定义。这创建了一个简单的闭包。
;;; foo.el --- toto -*- lexical-binding: t -*-
(defun make-adder3 (n) (lambda (x) (+ n x)))
(fset 'ad3 (make-adder3 3))
(symbol-function 'ad3)
回报:
(closure ((n . 3) t) (x) (+ n x))
(symbol-function 'make-adder1)
回报:
(lambda (n)
(list (quote lambda)
(quote (x))
(cons (quote +) (cons n (quote (x))))))
(symbol-function 'make-adder2)
回报:
(closure (t)
(n)
(let ((--cl-n-- (make-symbol "--n--")))
(let* ((v --cl-n--)) (set v n))
(list (quote lambda)
(quote (&rest --cl-rest--))
(list (quote apply)
(list (quote quote)
(function
(lambda (G69709 x)
(+ (symbol-value G69709) x))))
(list (quote quote) --cl-n--)
(quote --cl-rest--)))))
(symbol-function 'make-adder3)
个
回报
(closure (t) (n) (function (lambda (x) (+ n x))))
这必须是重复的,但我没有时间去寻找它... – Drew