【发布时间】:2012-04-26 11:38:57
【问题描述】:
我想提供一个可以被覆盖的默认值。我知道我可以使用三元组,如下所示:
(def foo (if (not (nil? bar)) bar baz))
但在 Clojure 中肯定有一种更惯用的方式来表示“使用 bar,如果 bar 为 nil,则使用 baz。
有什么建议吗?
【问题讨论】:
我想提供一个可以被覆盖的默认值。我知道我可以使用三元组,如下所示:
(def foo (if (not (nil? bar)) bar baz))
但在 Clojure 中肯定有一种更惯用的方式来表示“使用 bar,如果 bar 为 nil,则使用 baz。
有什么建议吗?
【问题讨论】:
这将分配bar,除非它是nil 或false,否则分配baz。
(def foo (or bar baz))
编辑
如果您想精确检查nil,您可以稍微优化您的原始代码,如下所示:
(def foo (if (nil? bar) baz bar))
我相信,这是最短的方法,虽然不是惯用的。
【讨论】:
nil 和 false 的习语。
bar 和baz,比如(if (nil? bar) baz bar)),你将摆脱@987654333 @,而且它几乎没有变短。
您的问题并未具体询问多个 var,但如果您确实希望对多个 var 进行这种默认设置,惯用的方法是使用 :or 默认值在 map 上进行解构。
例如使用这个带有映射参数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
【讨论】:
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
【讨论】: