在不使用(setq foo 1)
定义变量foo
的情况下将defvar
添加到代码中将导致Emacs字节编译器生成以下警告:
assignment to free variable `foo'
在没有事先定义的情况下分配给这样的自由变量有什么危险?
答案 0 :(得分:8)
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
),则后果可能无法预测。
简而言之,如果您在一个地方使用自由变量,则没有理由不绑定它。
如果你使用它来传递状态,你应该defvar
它并使用一个不太可能被其他人使用的长名称 - 你应该重构你的代码以避免这种情况。