【发布时间】:2015-11-22 14:14:00
【问题描述】:
Clojure 有一个 declare 宏,允许您前向声明函数或变量。它的功能似乎与 def 完全一样:(declare x) 和 (def x) 创建 #<Unbound Unbound: #'user/x>
什么时候应该使用(declare x) 而不是(def x)?
【问题讨论】:
标签: clojure forward-declaration
Clojure 有一个 declare 宏,允许您前向声明函数或变量。它的功能似乎与 def 完全一样:(declare x) 和 (def x) 创建 #<Unbound Unbound: #'user/x>
什么时候应该使用(declare x) 而不是(def x)?
【问题讨论】:
标签: clojure forward-declaration
declare 和 def 都会创建一个未绑定的 var,但使用 declare 有 3 个优点:
(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.
Looking at the implementation,很明显declare 是根据def 定义的,并提供了一点语法糖。所以在功能上,它们几乎是一样的。
declare 的优点是为以后的读者显示意图。 (declare x y z) 表示我打算对这些符号进行前向声明,因为宏是 useful for making forward declarations.
(def x) (def y) (def z) 表示我正在实习这些符号,但你不知道我是否打算给它们定义而忘记了,或者我是否在进行前向声明,或者其他一些微妙的东西。
因此,在进行前向声明时,(declare x) 应该优先于 (def x),以便对代码的未来读者表示怜悯。
【讨论】:
def 始终适用于根绑定,即使 var 在调用 def 时是线程绑定的。
def 产生 var 本身(而不是它的值)。如果符号已在命名空间中且未映射到内部变量,则引发异常。
声明defs 提供的不带绑定的var 名称,用于进行前向声明。
【讨论】: