我看到其他人的eLisp代码中使用了尖锐的引号,而我自己也使用了引号,但是我不清楚它们什么时候合适,什么时候不合适。
谁能确切说明何时应使用尖引号以及何时应使用普通单引号?
#'
与lambda一起使用的(答案基本上是“从不”),而@izkon的问题适用于将#'
符号应用于符号。
我看到其他人的eLisp代码中使用了尖锐的引号,而我自己也使用了引号,但是我不清楚它们什么时候合适,什么时候不合适。
谁能确切说明何时应使用尖引号以及何时应使用普通单引号?
#'
与lambda一起使用的(答案基本上是“从不”),而@izkon的问题适用于将#'
符号应用于符号。
Answers:
#'
只是简写function
,就像'
简写quote
。
您可以在希望向字节编译器,解释器或人工阅读器表明其自变量为(被视为)函数的地方使用它。
在许多情况下,上下文决定了参数的处理方式,例如,如果仅引用(使用quote
或'
)而不是使用#'
(或function
),则如何处理。例如,在仅将符号用作symbol-function
属性的情况下(即,将其用作函数),您可以仅传递符号(例如,将其引号或传递其值为符号的变量)。
但是,如果您确实#'
在这样的上下文中使用,有时代码会更清晰。即使Emacs-Lisp本身理解在这种情况下将符号用作功能,对于人类的代码阅读者来说也可能有助于强调这一点。
在其他一些Lisps中,简单引号(用'
)或未引号的lambda形式的处理可能与在函数位置使用function
(#'
)引用时的用法不同。但不是在Emacs Lisp中。在Emacs Lisp中,您不需要引用(使用'
或#'
)要作为函数(而不仅仅是列表)的lambda形式。如果您确实希望将其仅作为列表,汽车lambda
等处理,则将其引号(带有'
),以下示例对此进行了说明。
来自(省略号)匿名函数:
-特殊形式:
function
function-object
此特殊形式返回
FUNCTION-OBJECT
而不评估它。在此,它类似于
quote
(* note Quoting::)。但是,与不同quote
,它还用作Emacs评估程序和字节编译器的注释,该注释FUNCTION-OBJECT
旨在用作功能。假设FUNCTION-OBJECT
是有效的lambda表达式,则有两个作用:•将代码按字节编译时,将
FUNCTION-OBJECT
被编译为字节码功能对象(*请注意Byte Compilation::)。•启用词法绑定时,
FUNCTION-OBJECT
将转换为闭包。*注意关闭::。读取语法
#'
是使用的简写function
。以下形式都是等效的:(lambda (x) (* x x)) (function (lambda (x) (* x x))) #'(lambda (x) (* x x))
在下面的示例中,我们定义一个
change-property
函数,该函数将一个函数作为其第三个参数,然后是一个通过将其传递给匿名函数来double-property
使用的change-property
函数:(defun change-property (symbol prop function) (let ((value (get symbol prop))) (put symbol prop (funcall function value)))) (defun double-property (symbol prop) (change-property symbol prop (lambda (x) (* 2 x))))
请注意,我们不引用该
lambda
表格。如果编译上面的代码,还将编译匿名函数。例如,如果您通过将匿名函数引用为列表来构造匿名函数,则不会发生这种情况:
(defun double-property (symbol prop) (change-property symbol prop '(lambda (x) (* 2 x))))
在这种情况下,匿名函数将作为lambda表达式保留在编译后的代码中。即使看起来像一个字节编译器,字节编译器也不能假定它是一个函数,因为它不知道
change-property
打算将其用作函数。
#'
(aka function
)可以在的前面使用,(lambda ...)
但在那里是多余的,因此真正有意义的唯一地方是在符号的前面,如中所示#'car
。在elisp的,#'car
并且'car
几乎完全相等的,所以的主要目的之一是简单地记录了意向(即指示谁读取这个代码,您打算使用这个符号作为一个功能)。但是,在某些情况下,差异更大:
#'car
时将检查它是否car
作为一个函数存在,如果找不到,它会发出警告,就像调用该函数一样。 。在cl-flet
和中cl-labels
,只能#'f
引用本地定义的函数f
,因为'f
仍将引用全局符号f
(以及可能存储在其symbol-function
插槽中的任何函数)。例如
(cl-flet ((car (x y) (+ x y)))
(list #'car 'car))
=>
((closure nil (x y) (+ x y)) car)