这是我的 Common Lisp 代码:
(defun caller (f)
(format t "caller: f: ~a~%" f)
(funcall f 10))
(defun callee (x)
(format t "callee: x: ~a~%" x))
(caller #'callee)
(caller 'callee)
这是我使用 clisp
得到的输出:
$ clisp foo.lisp
caller: f: #<FUNCTION CALLEE (X) (DECLARE (IN-DEFUN CALLEE)) (BLOCK CALLEE (FORMAT T callee: x: ~a~% X))>
callee: x: 10
caller: f: CALLEE
callee: x: 10
我想知道语法#'callee
和语法'callee
之间有什么区别。
尽管使用这两种语法,我都能够将 callee
传递给 caller
,但 caller: f:
输出似乎表明这两种语法有一些细微的差别:#'callee
似乎是指函数对象,而 'callee
似乎只是指函数名称。
这是我的问题:
#'callee
语法和'callee
语法有什么区别?- 在这两种情况下,
funcall
是如何成功调用callee
的? - 由于哪一种语法优于另一种语法,是否存在与这两种语法相关的最佳实践或优缺点?
最佳答案
主要区别在于查找函数的方式。如果将一个符号传递给 funcall
,它会在全局(而不是词法)环境中查找。相关文档为http://clhs.lisp.se/Body/f_funcal.htm .我稍微修改了文档中的示例:
(defun cons* (&rest rest)
(apply 'cons rest))
(flet ((cons* (x y) `(kons ,x ,y)))
(let ((cons* (symbol-function '+)))
(funcall #'cons*
(funcall 'cons* 1 2)
(funcall cons* 1 2))))
;; => (KONS (1 . 2) 3)
关于function - Common Lisp中#'callee and '被调用者之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50451186/