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

And*_*bis 4 emacs elisp

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

assignment to free variable `foo'
Run Code Online (Sandbox Code Playgroud)

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

sds*_*sds 8

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使用它并使用一个不太可能被其他人使用的长名称 - 你应该重构你的代码以避免这种情况.

  • 确实,无害而又愚蠢.请记住,您为其他人(以及明年自己!)编写代码来读取它,而不仅仅是计算机执行它.通过添加`defvar`,您将添加一个关键的文档. (3认同)