鉴于此示例代码(来自 Reddit /r/lisp question ):
(defun next (pos)
(nth (1+ pos)
'(0 1 2 3 4 5 6 7 8 9 10)))
(defvar *next* (function next))
(let ((old-next #'next)
(previous (make-hash-table)))
(format t "~% 1 EQ? ~a" (eq old-next *next*))
(defun next (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-next pos))))
(format t "~% 2 EQ? ~a" (eq old-next *next*)))
以上创建函数
NEXT
.里面
LET
,我们将旧函数保留在
OLD-NEXT
.然后我们重新定义全局函数
NEXT
里面
LET
.
CCL/CMUCL/GCL/ECL/CLISP/LispWorks/ABCL:
? (load "test.lisp")
1 EQ? T
2 EQ? T
只有 SBCL (SBCL 1.3.11) 有不同的结果:
* (load "test.lisp")
1 EQ? T
2 EQ? NIL
局部变量的值
old-next
不再是
eq
到全局变量
*next*
的值.
为什么???
请您参考如下方法:
无论变量是否特殊,行为都会发生变化:
(inspect
(progn
(defun next ())
(let ((old #'next)
(foo #'next))
(declare (special foo))
(defun next () :different)
(list old foo))))
The object is a proper list of length 2.
0. 0: #<FUNCTION NEXT>
1. 1: #<FUNCTION NEXT {10037694EB}>
第一个元素指的是最新的定义,而第二个元素是从特殊变量中获得的,正如预期的那样,是旧的定义。
当您删除特殊声明时,两个引用都是 EQ(并指向新定义)。