2010-01-06 6 views

Répondre

69

je suppose que if-let doit être utilisé lorsque vous souhaitez faire référence à une valeur de l'état if dans la « then » une partie du code:

-à-dire au lieu de

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

vous écrivez:

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

qui est un peu plus propre, et vous évite d'indenter un niveau supplémentaire. En ce qui concerne l'efficacité va, vous pouvez voir que l'expansion macro n'ajoute pas de frais généraux:

(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))) 

Cela montre aussi que la liaison ne peut être mentionné dans la partie « else » du code.

+9

De plus, il est impossible d'avoir plus de 2 formes dans le vecteur de liaison de if-let. Par exemple: (si-let [un 20 b nul] (println a)) - ne fonctionne pas! –

+1

Il y a aussi 'when-let'. –

30

Un bon exemple d'utilisation pour if-let est de supprimer le besoin d'utiliser une anaphore. Par exemple, le langage de programmation Arc fournit une macro appelée aif qui vous permet de lier une variable spéciale nommée it dans le corps d'un formulaire if lorsqu'une expression donnée est évaluée comme étant logique vraie. Nous pouvons créer la même chose dans Clojure:

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

(aif 42 (println it)) 
; 42 

Ceci est beau et bon, sauf que anaphore ne nichent pas, mais if-let fait:

(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

Trouvé très utile. – octopusgrabbus