2015-11-22 14 views
15

Clojure, ha una macro declare che consente di inoltrare funzioni o variabili. Sembra funzionare esattamente come def: Sia (declare x) e (def x) creare #<Unbound Unbound: #'user/x>`def` vs` dichlare` per inoltro dichiarazione

Quando deve (declare x) essere usato al posto di (def x)?

risposta

17

Sia declare e def fare creare un var non legato, ma ci sono 3 vantaggi nell'utilizzo di declare:

  1. È possibile creare più Vars in una dichiarazione, per esempio (declare x y z)
  2. I Vars sono contrassegnati con l'metadati aggiuntivi {:declared true}
  3. Utilizzando la parola declare è senza dubbio più chiaro e idiomatica

(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

La documentazione dà la risposta:

=> (doc declare) 
------------------------- 
clojure.core/declare 
([& names]) 
Macro 
    defs the supplied var names with no bindings, useful for making forward declarations. 

Looking at the implementation, è chiaro che declare è definito in termini di def e fornisce un po 'di zucchero di sintassi. Quindi, funzionalmente, sono praticamente la stessa cosa.

Il vantaggio di declare è mostrare l'intento di un lettore successivo. (declare x y z) significa che ho intenzione di fare una dichiarazione anticipata di quei simboli, perché la macro è useful for making forward declarations.

(def x) (def y) (def z) significa che sono internato questi simboli, ma non so se volevo dare loro definizioni e dimenticato di o se io sto facendo dichiarazioni in avanti, o forse qualcos'altro di sottile.

Quindi, (def x) deve essere preferito a (def x) quando si effettua una dichiarazione anticipata, per mostrare pietà ai futuri lettori del proprio codice.

1

def si applica sempre al collegamento radice, anche se la var è legata al thread nel punto in cui viene chiamato def.

def produce la variabile stessa (non il suo valore). Genera un'eccezione se il simbolo è già nello spazio dei nomi e non è mappato su una var interna.

Dichiarare def s i nomi var forniti senza binding, utili per fare dichiarazioni in avanti.