3 回答
function
(aka #'
) 用于引用函数,而quote
(aka '
) 用于引用数据。现在,在 Emacs-Lisp 中,函数单元为函数的符号本身就是一个函数,因此与实践#'symbol
中的相同'symbol
(虽然意图不同,但首先要明确的是,不仅仅是在谈论符号“符号" 但关于名为 "symbol" 的函数)。
差异不仅仅是风格的地方在于引用 lambdas:'(lambda ...)
是一个表达式,其计算结果为一个列表,其第一个元素是符号lambda
。你可以对它应用 和 之类的东西car
,cdr
但你不应该把它当作一个函数来调用(尽管在实践中它往往工作得很好)。相反#'(lambda ...)
(可以写成(lambda ...)
)是一个计算为函数的表达式。这意味着你不能应用car
它,但字节编译器可以查看内部#'(lambda ...)
,在其中执行宏扩展,如果它发现的内容看起来不干净,则警告你,等等......;对于词法绑定,它甚至必须查看内部以找到该函数所引用的自由变量。
在 elisp#'
中(实际上)纯粹是关于字节编译(编辑:从 Emacs 24 开始,还有词法闭包);但您也可能永远不需要使用它。
#'...
是简写形式,(function ...)
它只是'...
/的变体,(quote ...)
它也暗示字节编译器可以将引用的形式编译为函数。
但是,在现代 Emacs(IIRC 并非总是如此)中,(lambda ...)
相当于 . #'(lambda ...)
,所以我相信您很少(如果有的话)需要编写#'
.
'(lambda ...)
由于 Stefan 详细阐述的原因(但没问题),您也很少想要使用'symbol
。
这在手册中有所介绍C-hig (elisp) Anonymous Functions
RET(尽管在最后一段示例代码中似乎存在错误,因为它与前面的示例相同(在 Emacs 24.3.1 中))。
(nb Stefan 的回答是确定的,但我将把这个留在这里,因为它希望能补充它。)
除了引用(lambda ...)
表单时的差异之外,最近(从 Emacs 24.4 开始)对bytecomp.el进行了更改,以便在使用表单时生成警告#'symbol
,但不知道该函数会在末尾定义汇编。
#'symbol
因此,使用函数引用语法而不是语法来编写所有函数符号'symbol
比较可取,因为它允许字节编译器检查您是否使用了实际定义的函数名称。
以前(Emacs 24.3 和更早版本),当您调用函数时字节编译器会发出警告,(no-such-function ...)
并且它没有定义或从另一个文件干净地导入,类似的东西(mapcar #'no-such-function ...)
只会产生运行时错误而没有编译时警告。
这一变化意味着这两种情况现在都会产生编译时警告;但是,如果您在(mapcar 'no-such-function ...)
不使用函数引用的情况下使用,那么再一次,不会生成编译时警告。因此#'
可以帮助及早发现错误(可能是拼写错误)。
函数引用也有助于自上而下的编程风格,因为字节编译器将列出您尚未实现的函数(但会错过使用普通引用指定的函数)。