Eli*_*son 9

这意味着您应该创建新变量而不是更改旧变量的值.例如,我们采用以下代码:

(defun foo (x)
  (when (minusp x)
    (setq x (- x)))
  do something with x)
Run Code Online (Sandbox Code Playgroud)

相反,应该创建一个新绑定并使用该绑定:

(defun foo (x)
  (let ((xabs (if (minusp x)
                  (- x)
                  x)))
    do something with xabs)
Run Code Online (Sandbox Code Playgroud)

这样做的原因是你总是知道变量包含什么,因为它永远不会改变.如果您想要新值,只需使用包含该新值的变量即可.

现在您可能会问为什么这么重要?嗯,有些人比其他人更喜欢这个.特别是那些喜欢强调Lisp功能方面的人会提倡这种风格.但是,无论偏好如何,始终能够依赖变量不会改变的事实是非常有用的.这是一个重要的例子:

(defun foo (x)
  (let ((function #'(lambda () (format t "the value of x is ~a~%" x))))
    (when (minusp x)
      (setq x (- x)))
    (other-function x)
    function))
Run Code Online (Sandbox Code Playgroud)

然后,返回值FOO是一个函数,当使用print调用值时x.但是,该值将是x函数后期的值,即绝对值.如果功能大而复杂,这可能会非常令人惊讶.

  • 引用修改后的值的闭包让我想起了如何在JavaScript中使用for循环迭代按钮数组并附加指向迭代索引的onclick处理程序是一个坏主意 (3认同)
  • @LeCurious在Common Lisp中出现了关闭迭代变量的问题,尤其是[loop macro](http://www.lispworks.com/documentation/HyperSpec/Body/m_loop.htm).例如,请参阅[循环宏和闭包的意外行为](http://stackoverflow.com/questions/15714537/unexpected-behavior-with-loop-macro-and-closures),它演示了这种确切的行为. (3认同)