2010-01-06 63 views

回答

69

我想if-let时,应使用你想在代码中的“then”部分引用if条件的值:即

代替

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

你写:

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

这是一个小整理者,并且可以节省您进一步缩进级别。至于效率会,你可以看到,宏扩展不会增加太多开销:

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

这也说明了绑定不能在代码中的“else”的部分被称为。

+9

此外,也不可能有超过2在if-let的绑定向量中形成。例如:(if-let [a 20b nil](println a)) - 不起作用! – 2010-06-04 11:18:56

+1

还有'当 - 让'。 – 2013-01-04 22:49:42

30

if-let的一个很好的用例是消除了使用回指的需要。例如,Arc编程语言提供了一个名为aif的宏,它允许您在给定表达式求值为逻辑真时,将一个名为it的特殊变量绑定在if表单的正文中。我们可以用Clojure创建同样的事情:

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

(aif 42 (println it)) 
; 42 

这是优秀和良好,但照应不嵌套,但if-let作用:

(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

发现非常有用。 – octopusgrabbus 2012-01-12 22:45:10