lisp - 设置全局变量恢复到最后一个值

标签 lisp common-lisp

当我尝试在方法中设置全局参数时,我遇到了一些奇怪的行为。

(defparameter *global-var-1* nil)

(defun method1 ()
   (setf *global-var-1* '())
   (format t "~a~%" *global-var-1*)

   ...
   (loop
      ...

      (setf *global-var-1* '(a))
      (format t "~a~%" *global-var-1*)

      (nconc *global-var-1* (list '(b c))))

在上面的代码中,当我调用 method1 时,第一个格式语句总是按预期打印 nil。第二个格式语句在第一次调用 method1 时打印 (A),但在第二次调用时打印 (A (B C))。第三次 (A (B C) (B C)) 以此类推。 setf 似乎没有将 *global-var-1* 设置为 (A),而是将其设置为先前的已知值。我究竟做错了什么?顺便说一句,我将 *global-var-1 设置为 (A) 因为 nconc 不能处理空列表。我稍后在退出 method1 之前删除了 (A)

最佳答案

当然 nconc 适用于空列表,但您必须始终分配其返回值,如下所示:

CL-USER> (defparameter *x* nil)
*X*
CL-USER> (setq *x* (nconc *x* (list 'a)))
(A)
CL-USER> *x*
(A)

然后,您的问题通过不使用文字列表得到解决:

CL-USER> (defparameter *x* nil)
*X*
CL-USER> (defun foo ()
           (setf *x* nil)
           (dotimes (n 3)
             (progn (setf *x* (list 'a))
                    (format t "~a~%" *x*)
                    (setf *x* (nconc *x* (list (list 'b 'c)))))))
FOO
CL-USER> (foo)
(A)
(A)
(A)

使用破坏性操作时应始终小心,并注意将它们与文字表达式一起使用的含义。在您的代码中,nconc 破坏性地修改了您的 '(a) 列表文字的 cdr,这导致了您观察到的行为。 (如果您不进行优化,您总是可以使用 append 来解决这个问题。)

您可能也对我的 other answer 感兴趣关于这个话题。

关于lisp - 设置全局变量恢复到最后一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8044060/

相关文章:

lambda - Land of Lisp 中关于 lisp Lambda 函数的问题

lisp - 重复调用格式忽略 ~t 选项

list - 返回列表中的特定元素 - LISP

heroku - 使用 Hunchentoot 在 Heroku 上使用 Common Lisp?

lisp - 普通口齿不清 : unable to load a file into the Lisp interpreter

struct - Lisp 中的嵌套结构

lisp - 修改函数的参数

emacs - 停止 lisp 要求用户输入

Lisp:确定列表是否包含谓词

java - 有没有一种方法可以直接循环遍历 Kawa 中的 Java Iterable 或者循环遍历 java.util.Iterator