Ответ 1
Важнейшим отличием между (or (:key hash) default)
и (:key hash default)
является тот факт, что первый оценивает default
, только если это необходимо. В последнем случае он всегда оценивается. Поэтому вы должны использовать or
, если оценка default
стоит дорого.
Другое отличие становится очевидным, когда ваш хэш содержит значения, которые являются ложными в булевом контексте. В случае таких значений (or (:key hash) default)
будет оцениваться до default
вместо false
или nil
, который вы ожидаете. В отличие от выражения or
, (:key hash default)
даст правильные результаты. В качестве примечания обратите внимание дважды, прежде чем хранить nil
как значения в хеше.
Хорошо, это были важные отличия. Теперь переходим к младшим.
(or (:title opts) "Default title")
расширяется читателем до
;; Redacted for the sake of brevity.
(let* [x (:title opts)]
(if x
x
"Default title"))
Возможно, он менее эффективен, чем просто оценить
(:title opts "Default title")
Конечно, без каких-либо тестов трудно оценить разницу в скорости, однако я считаю, что она должна быть маргинальной.
С другой стороны, на первый взгляд (or (:key hash) :default)
кажется более понятным для кого-то, кто не привык к идиоме (:key hash :default)
. Подумайте о программистах, поступающих с других языков. Например, в Ruby типичный подход к обработке несуществующего элемента хэша
val = hash[:key] || :default
Следовательно, первое выражение может быть проще проанализировать людьми, не привыкшими к некоторым идиомам Clojure.