“foo = bar || baz”的惯用 Clojure 是啥?

Posted

技术标签:

【中文标题】“foo = bar || baz”的惯用 Clojure 是啥?【英文标题】:What's the idiomatic Clojure for "foo = bar || baz"?“foo = bar || baz”的惯用 Clojure 是什么? 【发布时间】:2012-04-26 11:38:57 【问题描述】:

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

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

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

有什么建议吗?

【问题讨论】:

【参考方案1】:

这将分配bar,除非它是nilfalse,否则分配baz

(def foo (or bar baz))

编辑

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

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

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

【讨论】:

这很好,将解决我在代码中面临的问题,但我也想知道这样做时区分 nilfalse 的习语。 @JoshGlover 好吧,我不确定是否有一个特殊的成语,但如果你交换barbaz,比如(if (nil? bar) baz bar)),你将摆脱@987654333 @,而且它几乎没有变短。 好点,确实非常好。谢谢!如果您也更新您的答案以显示这种方式,我会接受它。【参考方案2】:

您的问题并未具体询问多个 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

【讨论】:

【参考方案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

【讨论】:

以上是关于“foo = bar || baz”的惯用 Clojure 是啥?的主要内容,如果未能解决你的问题,请参考以下文章

类 Foo\Bar\Baz 位于 ./foo/bar/utility/baz.php 不符合 psr-4 自动加载标准。跳过

用括号和逗号替换字符串中的逗号(如果它们不存在)

PDO令牌是否需要匹配bindValue 1:1?

nodejs部分

数组的结构赋值

数组的解构赋值