Clojure的方式是什么?“当...时做额外的事情”

时间:2014-11-25 10:35:46

标签: clojure functional-programming conditional

我有一个函数" my-func",它处理它作为参数获取的地图x并返回一个地图。处理时间很长,所以我把它转移到函数block-with-several-function-calls-on-x 如果传入的地图包含:special-key,则应在传出地图中添加其他键值对。

(defn my-func [x]
  (if (contains? x :special-key)
    (assoc (block-with-several-function-calls-on-x x)
           :extra-key true)
    (block-with-several-function-calls-on-x x)))

我真的想将block-with-several-function-calls-on-x的代码保留在my-func之内。我是其他编程语言,我只是将该部分的输出保存在变量中,并且(如果需要)之后添加附加部分而不是返回值。我被告知使用let不是" Clojuresque"。

将代码传递给函数(如上所述)是唯一的方法吗?或者是do-additonal-stuff-to-output-of-second-block - 函数:

(defn my-func [x]
  (do-additional-stuff-to-output-of-second-block
    (when (contains? x :special-key)
      (assoc :extra-key true))
    (block-with-several-function-calls-on-x x)))

3 个答案:

答案 0 :(得分:3)

cond->cond->>->->>的条件版本,可能符合您的需求:

(defn my-func
  [x]
  (cond-> (block-with-several-function-calls-on-x x)
    (contains? x :special-key) (assoc :extra-key true)
    (contains? x :other-key)   (dissoc :we-dont-need-this)))

虽然只有一个条件,但这可能不是可读性的缩影。

答案 1 :(得分:1)

尽管有你的建议,我还是会使用let

(defn my-func [x]
  (let [ans (block-with-several-function-calls-on-x x)]
    (if (contains? x :special-key)
      (assoc ans :extra-key true)
      ans)))

注意:

  • 你提到的唯一值是布尔值。如果 all 您的值是 布尔值,使用集合,而不是地图。
  • 如果没有,我怀疑你有假(falsenil)值。在 他们缺席,你可以用(contains? x :special-key)替换 (x :special-key)(:special-key x)

答案 2 :(得分:0)

以下选项可能比您当前的选项更具惯用性和简洁性。它避免重复调用block-with-several-function-calls-on-x函数,并使用when来表达条件中缺少替代函数的含义。

(defn block-with-several-function-calls-on-x [x]
  x)

(defn my-func [x] 
  (into (block-with-several-function-calls-on-x x)
        (when (contains? x :special-key)
          {:extra-key true})))

(my-func {:bla 1 :special-key 2})
;= {:bla 1, :special-key 2, :extra-key true}
(my-func {:bla 1})
;= {:bla 1}