预定义全局变量的词法绑定
lexical binding for a predefined global variable
这是让我感到困惑的片段:
(setq lexical-binding t)
(defvar x 0)
(setq test (let ((x 1))
(lambda ()
x)))
(funcall test)
我的理解是,既然lexical-binding
为真,那么取值1的x应该覆盖let
的范围,应该包括[=定义中的x
14=],因此,测试应该 return 值 1 而不是 0,但结果是 return 0,这是 x
的值 defvar
.
我是不是误会了什么?
更新
只是为了澄清,我想把我的理解放在这里。动态边界意味着它只有一个符号,并且值在堆栈中弹出和弹出。因此,当 lambda
的定义完成后,let 中使用的值将被弹出。
lexical/static bounding 意味着值总是在词法环境的上下文中被检查,所以只要在 lambda
定义之前有 let
,就使用 let
中的值。
defvar
定义的变量总是动态绑定的,因此,这里的词法绑定控制没有任何区别。
根据 https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html,即使 lexical-binding
不是 nil
,特殊变量(如 x
因为它是用 defvar
定义的)也是仍然动态绑定。
这是让我感到困惑的片段:
(setq lexical-binding t)
(defvar x 0)
(setq test (let ((x 1))
(lambda ()
x)))
(funcall test)
我的理解是,既然lexical-binding
为真,那么取值1的x应该覆盖let
的范围,应该包括[=定义中的x
14=],因此,测试应该 return 值 1 而不是 0,但结果是 return 0,这是 x
的值 defvar
.
我是不是误会了什么?
更新
只是为了澄清,我想把我的理解放在这里。动态边界意味着它只有一个符号,并且值在堆栈中弹出和弹出。因此,当 lambda
的定义完成后,let 中使用的值将被弹出。
lexical/static bounding 意味着值总是在词法环境的上下文中被检查,所以只要在 lambda
定义之前有 let
,就使用 let
中的值。
defvar
定义的变量总是动态绑定的,因此,这里的词法绑定控制没有任何区别。
根据 https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html,即使 lexical-binding
不是 nil
,特殊变量(如 x
因为它是用 defvar
定义的)也是仍然动态绑定。