在(setq foo 1)不foo使用变量定义的情况下添加代码defvar将导致Emacs字节编译器生成以下警告:
assignment to free variable `foo'
Run Code Online (Sandbox Code Playgroud)
在没有事先定义的情况下分配给这样的自由变量有什么危险?
Emacs Lisp 默认使用动态绑定,所以当你写
(defun my-fun-1 (...)
...
(setq foo 1)
...)
Run Code Online (Sandbox Code Playgroud)
并得到你的警告,代码相当于(defvar foo)之前的defun.
这意味着,my-fun-1上述股票的价值foo与
(defun maybe-start-ww3 ()
(when (= 1 foo)
(launch-missiles)))
Run Code Online (Sandbox Code Playgroud)
这并不总是坏事; 很多ELisp遗留代码使用这样的全局变量来传递状态.然而,这是一种非常糟糕的风格,如果你date在两个不相关的地方使用相同的变量名称(例如),后果可能是不可预测的.
简而言之,如果您在一个地方使用自由变量,则没有理由不绑定它.如果你使用它来传递状态,你应该defvar使用它并使用一个不太可能被其他人使用的长名称 - 你应该重构你的代码以避免这种情况.