Когда делает использование if-let
вместо let
заставьте код выглядеть лучше, и он оказывает какое-либо влияние производительности?
Наверное if-let следует использовать, когда нужно сослаться на значение условия if
в "then
" части кода:
i. e. вместо
(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
" части кода.
Хорошим вариантом использования if-let
является устранение необходимости использования анафоры. Например, язык программирования Arc предоставляет макрос с именем aif
, который позволяет связать специальную переменную с именем it
в теле формы if
, когда данное выражение вычисляется до логической истины. То же самое можно создать и в Кложуре:
(defmacro aif [expr & body]
`(let [~'it ~expr] (if ~'it (do ~@body))))
(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]