Когда используется if-let
вместо let
, чтобы код выглядел лучше и имел ли он какое-либо влияние на производительность?
Когда использовать let vs. if-let in Clojure
Ответ 1
Я думаю, if-let следует использовать, когда вы хотите ссылаться на значение условия if
в параметре then
часть кода:
то есть. вместо
(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
" кода.
Ответ 2
Хорошим вариантом использования для if-let
является удаление необходимости использования анафоры. Например, язык программирования Arc предоставляет макрос с именем aif
, который позволяет связать специальную переменную с именем it
внутри тела формы if
, когда данное выражение оценивает логическое значение true. Мы можем создать одно и то же в 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]