Lisp 预定义全局变量的词法绑定

Lisp 预定义全局变量的词法绑定,lisp,elisp,Lisp,Elisp,以下是让我困惑的片段: (setq词法绑定t) (defvar x 0) (setq试验(let((x 1)) (lambda() x) )) (所有测试) 我的理解是,既然词法绑定是真的,那么值1的x应该覆盖let的范围,这应该包括x在lambda的定义中,因此,测试应该返回值1而不是0,但结果是返回0,这是defvar的x值 我误解了什么吗 更新 为了澄清,我想把我的理解放在这里。动态边界表示它只有一个符号,值在堆栈中弹出。因此,当定义完lambda时,let中使用的值会弹出。 词法/静态

以下是让我困惑的片段:

(setq词法绑定t)
(defvar x 0)
(setq试验(let((x 1))
(lambda()
x) ))
(所有测试)
我的理解是,既然
词法绑定
是真的,那么值1的x应该覆盖
let
的范围,这应该包括
x
lambda
的定义中,因此,测试应该返回值1而不是0,但结果是返回0,这是
defvar
x

我误解了什么吗

更新 为了澄清,我想把我的理解放在这里。动态边界表示它只有一个符号,值在堆栈中弹出。因此,当定义完
lambda
时,let中使用的值会弹出。 词法/静态边界表示始终在词法环境的上下文中检查值,因此只要在
lambda
定义之前存在
let
,就会使用
let
中的值。
defvar
定义的变量总是动态绑定的,因此,这里的词法绑定控制没有任何区别。

根据,即使
词法绑定
是非
nil
,特殊变量(如
x
,因为它是用
defvar
定义的)仍然是动态绑定的。

我仍然感到困惑。实际上,无论词法绑定是否为真,(funcall test)始终返回0。不应该使用最新的值吗?(x1)不应该是最新的值吗?您熟悉动态绑定的工作原理吗?由于
x
是一个特殊的变量(因为它是用
defvar
定义的),所以它总是动态绑定的。无论
词法绑定
的值是多少,示例代码都没有词法绑定,因为您只处理一个特殊变量。也许更清楚的说法是,因为
x
是一个特殊变量,您没有在
let
中隐藏
x
,而是重新绑定它,但只有在
的范围内,才让
。即使在
let
内部,它仍然是相同的
x
,因此一旦
let
范围结束并调用函数,
x
已恢复到其原始值。要扩展Travis Sunderland的答案,
x
(它始终是一个动态变量,已使用
defvar
定义)在定义lambda函数时,具有
1
的动态绑定,但该绑定的范围在该定义发生后结束,因此调用该函数时,
x
不再绑定到
1
。因此,此代码中的
let
表单是多余的。而且,
(setq词法绑定t)
不是使用
词法绑定的经批准的方式。我不确定这样做是否有预期的效果。您应该只使用标题行注释来启用
词法绑定
作为库中的文件局部变量:
;-*-词汇结合:t-*-。请注意,您可以使用
M-x add file local variable prop line
插入该行。