42
4

3 回答 3

39

function(aka #') 用于引用函数,而quote(aka ') 用于引用数据。现在,在 Emacs-Lisp 中,函数单元为函数的符号本身就是一个函数,因此与实践#'symbol中的相同'symbol(虽然意图不同,但首先要明确的是,不仅仅是在谈论符号“符号" 但关于名为 "symbol" 的函数)。

差异不仅仅是风格的地方在于引用 lambdas:'(lambda ...)是一个表达式,其计算结果为一个列表,其第一个元素是符号lambda。你可以对它应用 和 之类的东西carcdr但你不应该把它当作一个函数来调用(尽管在实践中它往往工作得很好)。相反#'(lambda ...)(可以写成(lambda ...))是一个计算为函数的表达式。这意味着你不能应用car它,但字节编译器可以查看内部#'(lambda ...),在其中执行宏扩展,如果它发现的内容看起来不干净,则警告你,等等......;对于词法绑定,它甚至必须查看内部以找到该函数所引用的自由变量。

于 2013-05-28T22:09:04.833 回答
14

在 elisp#'中(实际上)纯粹是关于字节编译(编辑:从 Emacs 24 开始,还有词法闭包);但您也可能永远不需要使用它。

#'...是简写形式,(function ...)它只是'.../的变体,(quote ...)它也暗示字节编译器可以将引用的形式编译为函数。

但是,在现代 Emacs(IIRC 并非总是如此)中,(lambda ...)相当于 . #'(lambda ...),所以我相信您很少(如果有的话)需要编写#'.

'(lambda ...)由于 Stefan 详细阐述的原因(但没问题),您也很少想要使用'symbol

这在手册中有所介绍C-hig (elisp) Anonymous Functions RET(尽管在最后一段示例代码中似乎存在错误,因为它与前面的示例相同(在 Emacs 24.3.1 中))。

(nb Stefan 的回答是确定的,但我将把这个留在这里,因为它希望能补充它。)

于 2013-05-28T22:09:32.787 回答
7

除了引用(lambda ...)表单时的差异之外,最近(从 Emacs 24.4 开始)对bytecomp.el进行了更改,以便在使用表单时生成警告#'symbol,但不知道该函数会在末尾定义汇编。

#'symbol因此,使用函数引用语法而不是语法来编写所有函数符号'symbol比较可取,因为它允许字节编译器检查您是否使用了实际定义的函数名称。

以前(Emacs 24.3 和更早版本),当您调用函数时字节编译器会发出警告,(no-such-function ...)并且它没有定义或从另一个文件干净地导入,类似的东西(mapcar #'no-such-function ...)只会产生运行时错误而没有编译时警告。

这一变化意味着这两种情况现在都会产生编译时警告;但是,如果您在(mapcar 'no-such-function ...) 使用函数引用的情况下使用,那么再一次,不会生成编译时警告。因此#'可以帮助及早发现错误(可能是拼写错误)。

函数引用也有助于自上而下的编程风格,因为字节编译器将列出您尚未实现的函数(但会错过使用普通引用指定的函数)。

于 2013-09-24T13:18:03.927 回答