2010-01-06 18 views

risposta

69

immagino if-let dovrebbe essere usato quando si desidera fare riferimento il valore di un if di condizione nel "then" parte del codice:

cioè invece di

(let [result :foo] 
    (if result 
    (do-something-with result) 
    (do-something-else))) 

si scrive:

(if-let [result :foo] 
    (do-something-with result) 
    (do-something-else)) 

che è un po 'più ordinata, e ti fa risparmiare un ulteriore livello. Per quanto riguarda l'efficienza va, si può vedere che la macro di espansione non aggiunge molto in alto:

(clojure.core/let [temp__4804__auto__ :foo] 
    (if temp__4804__auto__ 
    (clojure.core/let [result temp__4804__auto__] 
     (do-something-with result)) 
    (do-something-else))) 

Questo dimostra anche che il legame non può essere di cui al "else" parte del codice.

+9

Inoltre, non è possibile avere più di 2 forme nel vettore vincolante di if-let. Ad esempio: (if-let [a 20 b nil] (println a)) - non funziona! –

+1

C'è anche "quando-lascia". –

30

Un caso di utilizzo corretto per if-let consiste nel rimuovere la necessità di utilizzare anafora. Ad esempio, il linguaggio di programmazione Arc fornisce una macro denominata aif che consente di associare una variabile speciale denominata it all'interno del corpo di un modulo if quando una determinata espressione restituisce true logico. Siamo in grado di creare la stessa cosa in Clojure:

(defmacro aif [expr & body] 
    `(let [~'it ~expr] (if ~'it (do [email protected])))) 

(aif 42 (println it)) 
; 42 

Questo va bene e buono, tranne che anafora non fare il nido, ma if-let fa:

(aif 42 (aif 38 [it it])) 
;=> [38 38] 

(aif 42 [it (aif 38 it)]) 
;=> [42 38] 

(if-let [x 42] (if-let [y 38] [x y])) 
;=> [42 38] 
+0

Trovato molto utile. – octopusgrabbus