Common lisp 获取“undefined variable”(未定义变量)警告,即使已定义

Common lisp 获取“undefined variable”(未定义变量)警告,即使已定义,common-lisp,sbcl,Common Lisp,Sbcl,在sbcl repl中执行下面的代码时,我得到了变量测试用例n的“undefined variable”警告。我在论坛上也遇到过类似的问题,如果一个变量在没有定义的情况下被设置为setf/setq,就会出现警告。但是我已经使用defparameter定义了这些变量,但是仍然得到了警告 我注意到的一件事是,如果我不引用format语句中的变量,警告就不会发生。 我也尝试过使用defvar。但它仍在发出警告。 有人能帮我理解为什么在statment中使用时会抛出警告,即使变量已定义 (def

在sbcl repl中执行下面的代码时,我得到了变量测试用例n的“undefined variable”警告。我在论坛上也遇到过类似的问题,如果一个变量在没有定义的情况下被设置为setf/setq,就会出现警告。但是我已经使用defparameter定义了这些变量,但是仍然得到了警告

我注意到的一件事是,如果我不引用format语句中的变量,警告就不会发生。 我也尝试过使用defvar。但它仍在发出警告。 有人能帮我理解为什么在statment中使用时会抛出警告,即使变量已定义

    (defun main ()
           (defvar test-cases 10)
           (defvar l 12)
           (defvar n 13)
           (format t "~a ~a ~a" test-cases l n))
下面解释了出现错误的原因,但请注意,很少需要从函数内部定义全局变量,大多数情况下,您将使用本地绑定

下面是一个简化的测试用例:

(defun foo () (defvar bar nil) bar)
在编译foo时,假设有一个新的CL环境,bar是未定义的。这就是编译器抱怨的原因。但是,如果调用foo,变量将被全局声明,然后返回其值

对的调用仅在执行时或在编译时(当它是顶级表单时)对全局环境产生影响:

但是,下面描述的编译时副作用只有在它们作为顶级表单出现时才会发生

副作用:如果defvar或defparameter表单显示为顶级表单,编译器必须识别该名称已声明为特殊名称。但是,它既不能计算初始值形式,也不能在编译时分配名为name的动态变量

因此,在函数体中编译对defvar的调用不会将符号声明为特殊变量。

下面解释了出现错误的原因,但请注意,很少需要从函数内部定义全局变量,大多数情况下,您将使用局部绑定

下面是一个简化的测试用例:

(defun foo () (defvar bar nil) bar)
在编译foo时,假设有一个新的CL环境,bar是未定义的。这就是编译器抱怨的原因。但是,如果调用foo,变量将被全局声明,然后返回其值

对的调用仅在执行时或在编译时(当它是顶级表单时)对全局环境产生影响:

但是,下面描述的编译时副作用只有在它们作为顶级表单出现时才会发生

副作用:如果defvar或defparameter表单显示为顶级表单,编译器必须识别该名称已声明为特殊名称。但是,它既不能计算初始值形式,也不能在编译时分配名为name的动态变量

因此,在函数体中编译对defvar的调用不会将符号声明为特殊变量。

defvar用于顶级定义的全局变量。使用LET定义局部变量。请参见DEFVAR,了解顶级定义的全局变量。使用LET定义局部变量。看见