Rai*_*wig 7 sbcl common-lisp ansi-common-lisp
给出这个示例代码(来自Reddit/r/lisp问题):
(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*)))
Run Code Online (Sandbox Code Playgroud)
以上建立了一个功能NEXT.在里面LET,我们保留旧功能OLD-NEXT.然后我们重新定义了NEXT内部的全局函数LET.
CCL/CMUCL/GCL/ECL/CLISP/LispWorks/ABCL:
? (load "test.lisp")
1 EQ? T
2 EQ? T
Run Code Online (Sandbox Code Playgroud)
只有SBCL(SBCL 1.3.11)有不同的结果:
* (load "test.lisp")
1 EQ? T
2 EQ? NIL
Run Code Online (Sandbox Code Playgroud)
局部变量的值old-next不再eq是全局变量的值*next*.
为什么???
看起来 SBCL 正在尝试变得聪明并优化变量。
(defun foobar ()
(print :foo))
(let ((old #'foobar))
(funcall old)
(defun foobar ()
(print :bar))
(funcall old))
Run Code Online (Sandbox Code Playgroud)
印刷
:FOO
:BAR
Run Code Online (Sandbox Code Playgroud)
但如果你使用SETF变量,
(defun foobar ()
(print :foo))
(let ((old #'foobar))
(funcall old)
(setf old #'foobar)
(defun foobar ()
(print :bar))
(funcall old))
Run Code Online (Sandbox Code Playgroud)
它打印
:FOO
:FOO
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |