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

发布于 2024-12-14 05:13:21 字数 701 浏览 0 评论 0原文

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

(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 (BC))。第三次(A (BC) (BC)) 依此类推。 setf 似乎没有将 *global-var-1* 设置为 (A),而是将其设置为之前的已知值。我做错了什么?顺便说一句,我将 *global-var-1 设置为 (A) 因为 nconc 不适用于空列表。我稍后在退出 method1 之前删除 (A)

I'm getting some strange behavior when I try to set a global parameter within a method.

(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))))

In the above code, when I call method1, the first format statement always prints nil as expected. The second format statement prints (A) the first time method1 is called, but the second time it prints (A (B C)). The third time (A (B C) (B C)) and so on. Instead of setting *global-var-1* to (A), setf seems to be setting it to the previous known value. What am I doing wrong? BTW, I was setting *global-var-1 to (A) because nconc won't work with an empty list. I remove (A) later on before exiting method1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

初见你 2024-12-21 05:13:22

当然,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 来解决此问题。)

您可能也对我的 关于此主题的其他答案

Of course nconc works with empty lists, but you must always assign its return value, like this:

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

Then, your problem is solved by not using literal lists:

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)

You should always be careful when using destructive operations, and be aware of the implications of using them with literal expressions. In your code, nconc destructively modified the cdr of your '(a) list literal, which results in the behavior you observed. (You could always use append to get around this, if you're not optimizing.)

You might also be interested in my other answer about this topic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文