这是关于函数define中的变量绑定的问题:
如果我像这样定义funcion“total”,则“total”中的x将绑定到let中的本地x。
CL-USER> (let ((x 0))
(defun total (y)
(incf x y)))
TOTAL
CL-USER> (defvar x 10000)
X
CL-USER> (total 1)
1
但是,如果我像这样定义“total”,x将在defvar中绑定到global x:
CL-USER> (defvar x 10000)
X
CL-USER> (let ((x 0))
(defun total (y)
(incf x y)))
TOTAL
CL-USER> (total 1)
10001
为什么这样?我需要一个解释来理解它。 环境是windows + emacs + slime + sbcl.Thanks。
答案 0 :(得分:6)
DEFVAR将符号(此处为X)建立为动态变量(“特殊”)。一旦完成,它的动态性将由LET和lambda列表保留(这就是为什么你总是用* earmuffs *命名特殊变量的一个原因)。所以在第二个例子中,TOTAL中的X将在调用TOTAL的动态环境中查找。当你在顶级调用它时,它会看到X的顶级绑定,它的值为10000.你也可以在另一个重新绑定X的LET中调用TOTAL,它将在持续时间内使用该值: / p>
* (let ((x 1000)) (total 5))) 1005 * (total 1) 10002
在第一个例子中,X没有被标记为特殊,所以LET正常地将它绑定在词汇上。随后的DEFVAR不会追溯性地影响TOTAL,因为DEFUN已经抓住了LET创建的词法环境,并将其用于引用X(基本上,将其隐藏在DEFVAR中。)