习惯性的clojure有条件地调用函数

时间:2012-02-03 23:50:13

标签: clojure idioms idiomatic

我有一个clojure函数,如果特定条件为真,需要将信息推送到地图中,使用该映射作为另一个函数的参数。

我有以下内容,但重复调用条形函数会感觉很笨拙。

(defn foo ([opts]

  (if (= true (something))       
    (bar (into opts {:a b}))
    (bar opts)))

(def bar [opts])

所以,如果(某事)是真的,我们在调用bar函数之前将额外的选项推入opts参数,否则我们只是将其传递。

4 个答案:

答案 0 :(得分:7)

首先,(= true (something))可以简单地由(something)替换而没有任何问题(除非您实际上试图区分true的返回值和返回值,比如说,1)。如果返回值的选项为truefalse,则(something)本身可以正常工作。您也可以使用merge而不是into,这可能会更加清晰。

你可以尝试

(bar (if (something)
       (merge opts {:a b})
       opts))

这也可以,虽然它涉及merge为假时不必要地调用(something),但是对于第二个参数nilmerge应该很快返回。

(bar (merge opts
            (when (something)
              {:a b})))

答案 1 :(得分:2)

retief的回答没问题。应该注意的是if是Clojure中的表达式而不仅仅是条件构造。因此,它具有返回值,您可以使用返回值作为函数的参数:

(bar (if (something)       
        (into opts {:a b})
         opts))

您可以将其视为Java中的三元运算符。

答案 2 :(得分:0)

将条件代码重构为函数。类似的东西:

(defn addAIfSomethig [opt] (if (something) (into opts {:a "A"}) opt) )
(defn addBIfSomethig [opt] (if (something) (into opts {:b "B"}) opt) )

然后在你的函数中,你需要在调用bar之前修改opt使用函数组合。

(defn foo [opt]
    (let [modifiers (comp addAIfSomethig addBIfSomethig)]
      (bar (modifiers opt))
    ))

答案 3 :(得分:0)

请注意,因为Clojure 1.5可以写这个

{{1}}