在第一個示例中,結果函數中沒有變量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