我做了一个简单的测试函数,试图通过调用(测试j 10)为j赋值。 我得到SYSTEM :: READ-EVAL-PRINT:变量J没有值。
(DEFUN test (j i)
(LET ((j i))
(print j)
)
)
答案 0 :(得分:1)
我不确定您是否知道j
中的let
和j
中的变量test
是两个完全不同的变量。因为真正的重构是将它们重命名以便清楚,所以删除了这些歧义的代码:
(defun test (pj pi)
(let ((lj pi))
(print lj)))
这是完全相同的代码,因为let
中的 new 绑定有效地使得具有相同名称的旧变量在let的持续时间内不可访问。警告将大约为pj
,因为它在函数中仍未使用,因此您应该考虑将其删除:
(defun test (pi)
(let ((lj pi))
(print lj)))
通常有一个未使用的参数是一个错误所以CL唠叨这样的事情。但是,有时您会使用更高阶函数来使用传递值的函数。例如。
(defun map-assoc (fn lst)
(loop :for n :from 0
:for (k . v) :in lst
:collect (funcall fn k v n lst)))
现在想象你想要列出一个关键字。
(defun assoq-keys (lst)
(map-assoc (lambda (k v n lst)
(declare (ignore v n lst))
k)
lst))
(assoq-keys '((I . 1) (II . 2) (III . 3) (IV . 4) (V . 5)))
; ==> (I II III IV V)
declare
语句将抑制传递的其他变量不会被使用的错误,但是您必须包含它们,因为它是map-assoc
函数的合同。对于一个获取其值或者可能交换其他值的函数,您将使用其他变量,因此传递值是一个很好的推广。
答案 1 :(得分:0)
我认为你误解了论据是如何运作的。您当前的test
函数有两个参数:j
和i
。你好像只使用i
,所以没有理由传递第二个。{1}}。考虑
(defun test (i)
(let ((j i))
(print j)))
然后将其称为(test 10)
。