Подтвердить что ты не робот

Какая идиоматическая Clojure для "foo = bar || baz"?

Я хочу указать значение по умолчанию, которое можно переопределить. Я знаю, что могу использовать тернар, например:

(def foo (if (not (nil? bar)) bar baz))

Но, конечно, в Clojure есть более идиоматический способ сказать "use bar", или baz, если bar равен нулю.

Любые предложения?

4b9b3361

Ответ 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