假设我有一个名为elisp-defvar-test.el
包含的文件:
;;; elisp-defvar-test.el --- -*- lexical-binding: t -*-
(defvar my-dynamic-var)
(defun f1 (x)
"Should return X."
(let ((my-dynamic-var x))
(f2)))
(defun f2 ()
"Returns the current value of `my-dynamic-var'."
my-dynamic-var)
(provide 'elisp-dynamic-test)
;;; elisp-defvar-test.el ends here
我加载此文件,然后进入暂存缓冲区并运行:
(setq lexical-binding t)
(f1 5)
(let ((my-dynamic-var 5))
(f2))
(f1 5)
按预期返回5,表示的主体按预期f1
被my-dynamic-var
视为动态范围变量。但是,最后一种形式给出的变量变量为void my-dynamic-var
,表明该变量使用词法作用域。似乎与的文档不一致,该文档defvar
说:
该
defvar
表格还声明变量为“特殊”,所以它始终是动态即使势必lexical-binding
为t。
如果我更改defvar
测试文件中的表格以提供初始值,则该变量将始终被视为动态变量,如文档所述。谁能解释为什么变量的作用域由defvar
声明变量时是否提供初始值来确定?
如果很重要,这是错误回溯:
Debugger entered--Lisp error: (void-variable my-dynamic-var)
f2()
(let ((my-dynamic-var 5)) (f2))
(progn (let ((my-dynamic-var 5)) (f2)))
eval((progn (let ((my-dynamic-var 5)) (f2))) t)
elisp--eval-last-sexp(t)
eval-last-sexp(t)
eval-print-last-sexp(nil)
funcall-interactively(eval-print-last-sexp nil)
call-interactively(eval-print-last-sexp nil nil)
command-execute(eval-print-last-sexp)