2015-11-22 3 views
15

Clojureは、関数または変数を前方宣言できるようにするdeclareマクロを持っています。 defとして正確に機能しているようだ:(declare x)代わり(def x)の使用する必要がある場合は(declare x)(def x)の両方が#<Unbound Unbound: #'user/x>`def`は前方宣言のための` declare`です。

を作成しますか?

答えて

17

両方declaredefが結合していないVARを作成して行うが、declareを使用しての3つの利点があります。

  1. あなたは、例えば、1つのステートメントで複数のVARSを作成することができます(declare x y z)
  2. VARSは、追加のメタデータ単語declareを使用して{:declared true}
  3. でタグ付けされているが、

(source declare) 間違いなくより明確かつ慣用である:

(defmacro declare 
    "defs the supplied var names with no bindings, useful for making forward declarations." 
    {:added "1.0"} 
    [& names] `(do [email protected](map #(list 'def (vary-meta % assoc :declared true)) names))) 
3

ドキュメントは答えを与えます:

Looking at the implementationdeclaredefで定義されており、構文の砂糖を少し提供しています。機能的には、ほとんど同じです。

declareの利点は、後の読者の意図を示すことです。マクロはuseful for making forward declarations.

(def x) (def y) (def z)私はこれらのシンボルをインターンてる意味が、私は彼らに定義を与えるためのものとするか、私かどうかを忘れてしまったかどうかわからないですので(declare x y z)は、私はそれらのシンボルの前方宣言を行うことを目的意味します前方宣言をするか、それとも他の微妙なものを作るでしょう。

したがって、コードの将来の読者に慈悲を表示するために、前方宣言を行っているときによりも(declare x)を優先する必要があります。

1

defは、defが呼び出された時点でvarがスレッドバインドされていても、常にルートバインディングに適用されます。

defは、var自体(その値ではありません)を生成します。 symbolが既に名前空間にあり、かつ内部変数にマップされていない場合は例外をスローします。

宣言def提供されたvar名はバインディングなしで、前方宣言に役立ちます。