Common Lisp,"已定义但从未使用过"

Car*_*sma 2 lisp common-lisp lisp-2 funcall

此函数编译警告,fn已定义且从未在第一行中使用,并且fn是第二行中未定义的函数:

(defun test-function (fn)
  (funcall #'fn))
Run Code Online (Sandbox Code Playgroud)

为什么?一般性解释或其链接将是伟大的.

PD:完整日志:

test.lisp:9:1:                                                                             
  style-warning:                                                                           
    The variable FN is defined but never used.                                             
    --> PROGN SB-IMPL::%DEFUN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA                          
    ==>                                                                                    
      #'(SB-INT:NAMED-LAMBDA TEST-FUNCTION                                                          
            (FN)                                                                           
          (BLOCK TEST-FUNCTION (FUNCALL #'FN)))                                                     


test.lisp:10:3:                                                                            
  style-warning:                                                                           
    undefined function: FN                                                                 
    ==>                                                                                    
      (SB-C::%FUNCALL #'FN)
Run Code Online (Sandbox Code Playgroud)

Ren*_*nzo 7

如果要调用作为参数传递的函数,或者将其分配给变量,只需使用变量或参数作为第一个参数funcall:

(defun test-function(fn)
  (funcall fn))

(test-function #'+)
;; => 0
Run Code Online (Sandbox Code Playgroud)

符号#'X(function X)(参见手册)的缩写,其中X 必须是函数的名称,例如使用defunor labelsflet或lambda表达式定义.因此,#'fn不起作用,因为fn它不是函数的名称,而是变量(在本例中是一个参数).

Common-Lisp是一个Lisp-2,即函数的命名空间不同于其他变量.因此,函数的名称是特殊的,你可以直接在一个表单中调用它们,而如果一个函数被赋给一个变量,它必须被调用(funcall name-of-the-variable arguments).

  • @zwol你实际上并不需要在那里使用`SYMBOL-FUNCTION`.如果用符号调用,`FUNCALL`将自行完成:`(funcall'+ 2 2)`=>`4`.`(test-function'+)`和`(test-function#'+)`之间的区别只是前者调用由`+`命名的当前函数,而后者调用由`+命名的函数. `在评估电话时.在这种情况下,结果应该是相同的,因为函数是立即调用的,但是如果函数存储在稍后要调用的某个地方,则可能同时重新定义. (2认同)