Какая идиоматическая Clojure для "foo = bar || baz"?
Я хочу указать значение по умолчанию, которое можно переопределить. Я знаю, что могу использовать тернар, например:
(def foo (if (not (nil? bar)) bar baz))
Но, конечно, в Clojure есть более идиоматический способ сказать "use bar", или baz, если bar равен нулю.
Любые предложения?
Ответы
Ответ 1
Это назначит bar
, если это не nil
или false
, а baz
иначе.
(def foo (or bar baz))
ИЗМЕНИТЬ
Если вы хотите точно проверить nil
, вы можете немного оптимизировать исходный код, например:
(def foo (if (nil? bar) baz bar))
Я считаю, что это самый короткий путь, хотя и не идиоматический.
Ответ 2
В вашем вопросе особо не задается вопрос о нескольких варах, но если вы хотите, чтобы это значение по умолчанию для более чем одного var, идиоматический способ сделать это - использовать деструктурирование на карте с :or
по умолчанию.
например. Возьмите эту функцию, которая принимает аргумент карты m
, ожидаемая карта имеет ключи от :a
, :b
и :c
, но если :b
и/или :c
не указаны, значения по умолчанию взяты из предложение :or
(defn foo [m]
(let [{:keys [a b c], :or {b 100 c 200}} m]
(println "a:" a)
(println "b:" b)
(println "c:" c)))
user> (foo {:a 1 :b 2})
a: 1 ; no default, use supplied value
b: 2 ; value supplied, default ignored
c: 200 ; no value supplied, use default from :or
nil
Ответ 3
fnil
также является опцией:
user> (def default-to (partial fnil identity))
#'user/default-to
user> (let [bar :foo
baz :default]
((default-to baz) bar))
:foo
user> (let [bar nil
baz :default]
((default-to baz) bar))
:default