我需要在let中定义一个函数,并能够立即使用它,如下所示:
(let ((test (lambda () (print "ha"))))
(test))
但是,由于测试是变量(而不是函数),因此它不起作用。相反,我需要像这样运行它:
(let ((test (lambda () (print "ha"))))
(funcall test))
就我而言,这是一个问题。我可以通过制作一个改变(测试)到(funcall测试)的宏来解决这个问题,但是,这不起作用,因为宏的名称将与我的情况中的方法相同(I' m猜测这会导致(测试)成为(funcall test)=>(funcall(funcall test))=> ...?)
有没有办法在lambda中定义一个方法并立即运行它,而不用像funcall这样的东西?
答案 0 :(得分:9)
见Special Operator FLET, LABELS, MACROLET
。请注意FLET
和LABELS
之间的差异。特别是,LABELS
可以定义(相互)递归函数,而FLET
可以隐藏现有函数,同时能够调用该函数本身:
(defun foo () (flet ((foo () (foo))) (foo)))
^1 ^2 ^1 ^2
(defun foo () (labels ((foo () (foo))) (foo)))
^1 ^2 ^2 ^2
答案 1 :(得分:6)
我可以通过制作一个更改(测试)到(funcall测试)的宏来解决这个问题,但这不起作用
为什么不呢?
CL-USER 4 > (let ((test (lambda () (print "ha"))))
(macrolet ((test ()
`(funcall test)))
(test)))
"ha"
"ha"
答案 2 :(得分:3)
您可以使用labels
,就像使用let
变量一样。即:
(labels ((test ()
(print "ha")))
(test))