在 Emacs Lisp 中分配给自由变量有什么危险?

What are the dangers of assigning to a free variable in Emacs Lisp?

在代码中添加 (setq foo 1) 而没有使用 defvar 定义变量 foo 将导致 Emacs 字节编译器生成以下警告:

assignment to free variable `foo'

在没有预先定义的情况下分配给这样的自由变量有什么危险?

Emacs Lisp 默认使用Dynamic Binding,所以当你写

(defun my-fun-1 (...)
  ...
  (setq foo 1)
  ...)

并收到警告,代码相当于在 defun 之前添加 (defvar foo)

这意味着上面的my-fun-1

共享foo的值
(defun maybe-start-ww3 ()
   (when (= 1 foo)
     (launch-missiles)))

这并不总是坏事;许多 ELisp 遗留代码使用这样的全局变量来传递状态。然而,这是一个 非常 糟糕的风格,如果你在两个不相关的地方使用相同的变量名(例如 date)用于这些目的,后果可能无法预测。

总之,如果你在单个地方使用自由变量,没有理由不绑定它。 如果您使用它来传递状态,您应该 defvar 它并使用不太可能被其他人使用的长名称 - 您应该重构您的代码以避免这种情况。