Clojure中有一个declare
宏,允许您前置声明函数或变量。它似乎与 def
宏完全相同: (declare x)
和 (def x)
都创建了 #<Unbound Unbound: #'user/x>
什么情况下应该使用 (declare x)
而不是 (def x)
?
Clojure中有一个declare
宏,允许您前置声明函数或变量。它似乎与 def
宏完全相同: (declare x)
和 (def x)
都创建了 #<Unbound Unbound: #'user/x>
什么情况下应该使用 (declare x)
而不是 (def x)
?
declare
和def
都会创建一个未绑定的变量,但使用declare
有以下三个优点:
(declare x y z)
{:declared true}
declare
更加清晰、符合惯用法(source declare)
:
(defmacro declare
"defs the supplied var names with no bindings, useful for making forward declarations."
{:added "1.0"}
[& names] `(do ~@(map #(list 'def (vary-meta % assoc :declared true)) names)))
=> (doc declare)
-------------------------
clojure.core/declare
([& names])
Macro
defs the supplied var names with no bindings, useful for making forward declarations.
从实现上看,很明显declare
是基于def
定义的,并提供了一点语法糖。所以从功能上来说,它们几乎是一样的。
declare
的优势在于向后读者展示意图。 (declare x y z)表示我打算提前声明这些符号,因为该宏“可用于进行前向声明”。
(def x) (def y) (def z)
表示我正在将这些符号加入到命名空间中,但您不知道我是否打算为它们提供定义并忘记了,还是我正在做前向声明,或者可能是其他微妙的事情。
因此,在进行前向声明时应首选(declare x)
而不是(def x)
,以便对代码未来读者有所帮助。
def
总是应用于根绑定,即使在调用def
时变量在线程中绑定。
def
返回变量本身(而不是其值)。如果符号已经存在于命名空间中并且未映射到一个内部变量,则会抛出异常。
使用没有绑定的提供的变量名称声明def
,有助于进行前向声明。