【问题标题】: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。

有什么建议吗?

【问题讨论】:

    标签: clojure idioms


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-04
        • 1970-01-01
        • 2020-10-03
        • 1970-01-01
        相关资源
        最近更新 更多