如何在递归函数中保留变量? 假设我有这个功能,想打印我输入的初始值,如果这样的话,这段代码不能完成这项工作,它只会返回 5。我该如何完成这项工作?我想这与 gensym 有关。
(defun cprog (x)
(let ((d x))
(if (< x 5)
(cprog (1+ x))
(print d))))
感谢您的宝贵时间!
递归调用后,返回当前参数。
(defun cprog (x)
(if (< x 5)
(cprog (1+ x))
(print x))
x)
(cprog 1)
将在递归结束时打印 5
并返回 1
.
Barmar 的回答 对于您的简单情况是可以的,但请注意这种实现的后果:它不能进行尾递归,因为每次调用
cprog
都必须存储在程序调用堆栈中,因为在每次 cprog
调用之后,x
必须退货。
没有尾递归对于你的简单案例来说不是问题,但在生产环境中你宁愿那样实现它:
(defun cprog (x &optional (res x))
(if (< x 5)
(cprog (1+ x) res)
(and (print x) res)))
在这个实现中,你使用尾递归,即:你的普通lisp编译器将你的递归转换为一个简单的循环(可以通过查阅那些函数的dissambly看到),因此你的程序调用堆栈不会被太多耗尽递归引起的函数调用。
在生产系统中,这很重要,因为您可能有很多递归,如果您不使用尾递归,则可能会出现“程序堆栈溢出”。