2010-01-06 33 views

Trả lời

69

Tôi đoán if-let nên được sử dụng khi bạn muốn tham khảo giá trị một if tình trạng của trong "then" một phần của mã:

tức là thay vì

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

bạn viết:

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

đó là một chút neater, và giúp bạn thụt lề một cấp độ hơn nữa. Theo như hiệu quả đi, bạn có thể thấy rằng việc mở rộng vĩ mô không thêm nhiều chi phí:

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

này cũng cho thấy việc các ràng buộc không thể được đề cập trong "else" một phần của mã.

+9

Ngoài ra, nó không thể có nhiều hơn 2 các dạng trong vector liên kết của if-let. Ví dụ: (nếu cho [a 20 b nil] (println a)) - không hoạt động! –

+1

Ngoài ra còn có 'khi-let'. –

30

Trường hợp sử dụng tốt cho if-let là loại bỏ nhu cầu sử dụng anaphora. Ví dụ, ngôn ngữ lập trình Arc cung cấp một macro được gọi là aif cho phép bạn liên kết một biến đặc biệt có tên là it bên trong phần thân của một biểu mẫu if khi một biểu thức nhất định đánh giá đúng logic. Chúng ta có thể tạo ra những điều tương tự trong Clojure:

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

(aif 42 (println it)) 
; 42 

Điều này là tốt và tốt, ngoại trừ Anaphora mà không làm tổ, nhưng if-let làm:

(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

Tìm thấy rất hữu ích. – octopusgrabbus

Các vấn đề liên quan