相关疑难解决方法(0)

循环宏和闭包的意外行为

为什么这些形式表现如此?

CL-USER>
(setf *closures*
      (loop for num in (list 1 2 3 4)
            collect (lambda ()
                      num)))
(     
#<COMPILED-LEXICAL-CLOSURE #x302004932E1F>
#<COMPILED-LEXICAL-CLOSURE #x302004932DCF>
#<COMPILED-LEXICAL-CLOSURE #x302004932D7F>
#<COMPILED-LEXICAL-CLOSURE #x302004932D2F>)
CL-USER> 
(funcall (first *closures*))
4
CL-USER> 
(funcall (second *closures*))
4
Run Code Online (Sandbox Code Playgroud)

我原本期望第一个funcall返回1,第二个返回2,等等.这个行为与Clozure Common Lisp和Steel-Bank Common Lisp实现一致.

如果我将循环宏重写为使用dolist的版本,我期望的是返回的内容:

(setf *closures*
      (let ((out))
        (dolist (item (list 1 2 3 4) (reverse out))
          (push (lambda () item) out))))
(
#<COMPILED-LEXICAL-CLOSURE #x302004A12C4F>
#<COMPILED-LEXICAL-CLOSURE #x302004A12BFF>  
#<COMPILED-LEXICAL-CLOSURE #x302004A12BAF>
#<COMPILED-LEXICAL-CLOSURE #x302004A12B5F>)
CL-USER> 
(funcall (first *closures*))
1
CL-USER> 
(funcall (second *closures*))
2
Run Code Online (Sandbox Code Playgroud)

CL-USER> …

common-lisp

4
推荐指数
1
解决办法
240
查看次数

标签 统计

common-lisp ×1