测试功能如下:
(defun fab (n)
(let ((res '(1 1)))
(loop for i from 2 to n do
(nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
res))
$ ECL
... EECL(Embeddable Common-Lisp)12.7.1(git:UNKNOWN)
...
>(fab 10)
(1 1 2 3 5 8 13 21 34 55 89)
>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 2 3 5 8 13 21 34 55 89 144 91 5 8 13 21 34 55 89 144
然后我重启ECL
>(fab 20)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946)
似乎" res"在(fac 10)之后没有被释放?
此致!
答案 0 :(得分:4)
您应该在(list 1 1)
表单中使用'(1 1)
而不是let
。在Common Lisp中,没有定义修改文字对象的效果。
(defun fib (n)
(let ((res (list 1 1))) ; (list 1 1) instead of '(1 1)
(loop for i from 2 to n
do (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res)))))
res))
答案 1 :(得分:1)
诸如'(1 1)之类的常量仅由编译器/解释器分配一次。您的代码在此列表中使用NCONC,修改,后续调用不再看到常量列表'(1 1),而是修改后的列表。在Common Lisp中,未指定在破坏性地修改常量表达式时会发生什么,并且一些实现甚至保护它们免受更改以避免此类意外。如果您需要一个新的常量,请按照人们的说法和使用(列表1 1)或完全避免使用NCONC。