宣告,声明,宣布

tus*_*and 21 lisp common-lisp

能否请您解释这三个符号之间的差异proclaim,declaim以及declare

sds*_*sds 27

它们是符号,而不是关键字.

  1. proclaim命名用于进行全局声明函数.你应该尽可能使用. declaim

  2. declaim命名一个来进行全局 声明(例如proclaim),它们在编译时也很有效.

  3. declare只是一个符号(ig,它没有命名函数,特殊运算符),用于在某些表单的开头创建局部 声明(您可以将其视为这些表单的语法元素).

因此,前两个影响全球环境,最后一个是本地环境.

declaim优于,proclaim因为它在编译环境中立即生效:

虽然proclaim表单的执行具有可能影响编译的效果,但编译器不会尝试识别并专门处理声明表单.下面的公式,即使是顶级表单,在执行之前也没有任何效果:

(proclaim '(special *x*))

如果需要编译时副作用, eval-when可能会有用.例如:

(eval-when (:execute :compile-toplevel :load-toplevel) (proclaim '(special *x*)))

然而,在大多数此类情况下,优选 declaim用于此目的.

即,如果您的代码是

(proclaim '(special *x*))
(defun foo () (print *x*))
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨foo读取未知的特殊变量*x*,而

(declaim (special *x*))
(defun foo () (print *x*))
Run Code Online (Sandbox Code Playgroud)

不会引起警告.

PS.如果你想知道为什么CL甚至有proclaim:首先,历史上它曾经在那里declaim,第二,proclaim在宏中更简单和有用.

  • sds:您过去为其他问题写了一些很好的答案,虽然您对声明、声明和声明的性质的总结非常正确,但其余的答案归结为阅读一本书或阅读 hyperspec。我很高兴看到这个问题的答案,因为当我使用 declaim 时,我对它的行为没有很好的直觉,而且我发现 hyperspec 关于这个主题的信息有点密集。您是否有机会扩展此答案以包括相关函数和宏的行为?谢谢 (2认同)