什么是“foo = bar || baz”的惯用语?

时间:2012-04-14 08:21:02

标签: clojure idioms

我想提供一个可以覆盖的默认值。我知道我可以使用三元组,如下:

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

但是肯定在Clojure中有一种更惯用的方式来说“使用吧,或者如果bar是零则为baz。”

有什么建议吗?

3 个答案:

答案 0 :(得分:27)

这将指定bar,除非nilfalse,否则baz

(def foo (or bar baz))

修改

如果您希望准确检查nil,可以略微优化原始代码,如下所示:

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

我相信,这是最短的方式,虽然不是惯用的。

答案 1 :(得分:4)

你的问题没有具体询问多个变量,但是如果你确实想要多个var的违约,那么惯用的方法就是在:or默认值的地图上使用解构。

e.g。采用此函数采用地图参数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

答案 2 :(得分:2)

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