我做了一个简单的测试函数,试图通过调用 (test j 10) 为 j 分配一个 i 的值。 我收到 SYSTEM::READ-EVAL-PRINT:变量 J 没有值。
(DEFUN test (j i)
(LET ((j i))
(print j)
)
)
最佳答案
我不确定你是否知道 let
和 j
中的变量 j
定义在 test 的参数中
是两个完全不同的变量。真正的重构是重命名它们以使其清晰,这是您的代码,消除了歧义:
(defun test (pj pi)
(let ((lj pi))
(print lj)))
这是完全相同的代码,因为 let
中的 new 绑定(bind)有效地使得在 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
制定的契约功能。对于采用它们的值或可能交换其他变量的函数,您将使用其他变量,因此传递值是一个很好的概括。
关于LISP : SYSTEM::READ-EVAL-PRINT: 变量 I 没有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49543095/