18

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

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

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

有什么建议么?

4

3 回答 3

29

这将分配bar,除非它是nilor falsebaz否则。

(def foo (or bar baz))

编辑

如果您想nil精确检查,您可以稍微优化您的原始代码,如下所示:

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

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

于 2012-04-14T08:25:29.690 回答
4

您的问题并没有具体询问多个变量,但是如果您确实希望对多个变量进行默认设置,那么惯用的方法是在地图上使用:or默认解构。

例如,使用这个带有 map 参数m的函数,预期的 map 的键为: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
于 2012-04-14T20:18:38.293 回答
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
于 2012-04-16T21:39:23.633 回答