将 (setq foo 1)
添加到代码中而不使用 foo
定义变量 defvar
将导致 Emacs 字节编译器生成以下警告:
assignment to free variable `foo'
在没有事先定义的情况下分配给这样的自由变量有什么危险?
最佳答案
Emacs Lisp 默认使用 Dynamic Binding,所以当你写
(defun my-fun-1 (...)
...
(setq foo 1)
...)
并得到你的警告,代码相当于在
(defvar foo)
之前有 defun
。这意味着上面的
my-fun-1
共享 foo
的值(defun maybe-start-ww3 ()
(when (= 1 foo)
(launch-missiles)))
这并不总是坏事;许多 ELisp 遗留代码使用这样的全局变量来传递状态。但是,这是一种非常糟糕的风格,如果您在两个不相关的地方出于这些目的使用相同的变量名(例如
date
),后果可能是不可预测的。简而言之,如果你在一个地方使用 free 变量,没有理由不绑定(bind)它。
如果您使用它来传递状态,您应该对其进行
defvar
并使用其他人不太可能使用的长名称 - 您应该重构您的代码以避免这种情况。关于emacs - 在 Emacs Lisp 中为自由变量赋值有什么危险?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33600816/