Clojure `转发声明的def`vs`declare`

Clojure `转发声明的def`vs`declare`,clojure,forward-declaration,Clojure,Forward Declaration,Clojure有一个declare宏,允许您转发声明函数或变量。它的功能似乎与def完全相同:(declare x)和(def x)创建#两个declare和def都创建了一个未绑定的var,但是使用declare有三个优点: (defmacro declare "defs the supplied var names with no bindings, useful for making forward declarations." {:added "1.0"} [& na

Clojure有一个
declare
宏,允许您转发声明函数或变量。它的功能似乎与
def
完全相同:
(declare x)
(def x)
创建
#两个
declare
def
都创建了一个未绑定的var,但是使用
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)))
  • 您可以在一条语句中创建多个变量,例如
    (declare x y z)
  • 这些变量被附加元数据标记为
    {:declared true}
  • 使用
    declare
    这个词可以说更清晰、更惯用

  • (源代码声明)


    文件给出了答案:

    => (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
    始终应用于根绑定,即使var在调用
    def
    的点上被线程绑定

    def
    生成var本身(而不是其值)。如果符号已在命名空间中且未映射到内部变量,则引发异常

    Declare
    def
    s提供的变量名不带绑定,用于进行正向声明