没有初始值的 defvar 不定义符号

defvar without initial value does not define the symbol

在接下来的 IELM 会话中显示,使用没有初始值的 defvar 定义变量不会定义变量的符号。 那为什么不用初值就用defvar呢?是否仅用于文档 and/or 编译器帮助?

ELISP> foo 
*** Eval error ***  Symbol's value as variable is void: foo
ELISP> (boundp 'foo)
nil
ELISP> (defvar foo)
foo
ELISP> (boundp 'foo)
nil
ELISP> (defvar foo t)
foo
ELISP> (boundp 'foo)
t
ELISP> 

此语法用于告诉字节编译器某个变量存在,而它不知道该变量是否存在,从而避免编译警告。

这在手册 C-hig (elisp) Compiler Errors :

• You can tell the compiler that a function is defined using
  ‘declare-function’.  *Note Declaring Functions::.

• Likewise, you can tell the compiler that a variable is defined
  using ‘defvar’ with no initial value.  (Note that this marks the
  variable as special.)  *Note Defining Variables::.

它还告诉 Emacs 该变量使用动态绑定(即 "special",如引用中所述)。当然,在 Emacs Lisp 中这是默认设置;但是在启用了词法绑定的库中,即使你没有特别需要给变量赋初值,但如果要动态绑定变量,也是有必要这么做的。

defvar 文档字符串也指出了后一点:C-hf defvar

The `defvar' form also declares the variable as "special",
so that it is always dynamically bound even if `lexical-binding' is t.