2012-02-03 91 views
4

我有一个clojure函数,如果特定条件为真,需要将信息推入地图,将该地图用作另一个函数的参数。有条件调用函数有条件地调用函数

我有以下几点,但是对重复调用bar函数感觉很笨拙。因此,如果(某事)是真的,我们会在调用bar函数之前将其他选项添加到opts参数中,否则我们只是传递它。

回答

7

第一件事是(= true (something))可以简单地通过(something)没有问题更换(除非你实际上是尝试的true一个返回值,比如说,1返回值来区分)。如果返回值的选项是truefalse,则(something)本身可以正常工作。你也可以使用merge来代替into,这可能会稍微清晰些。

你可以尝试

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

这会工作为好,尽管它需要调用merge不必要时(something)是假的,虽然与nil的第二个参数,merge应该很快返回。

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

由于'(进入{}无)=> {}',你可以做'(巴(进入OPTS(时(东西){:AB })))'。也可以使用'merge'而不是'into'。 – Jonas 2012-02-04 05:39:31

+0

@Jonas谢谢 - 更新 – Retief 2012-02-04 05:44:27

0

将条件代码重构为函数。喜欢的东西:

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

然后在你的功能,你需要调用栏使用功能组成之前修改选择。

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

我真的很感谢倒票,但增加原因作为评论会让它变得难以捉摸 – Ankur 2012-02-05 11:55:27

+0

在Clojure中使用'camelCase'函数名是不惯用的。你可以编写'(defn <* _-!magicalFruit!-_ *> [](+ 1 1))'',但是如果你不想让你的代码像“foo-bar” ,'foo-bar?','foo-bar!'和(可能)'foo-> bar',除非有其他的理由。 – 2012-02-20 03:25:21

+0

感谢有关clojure(和一般lisp)风格的信息 – Ankur 2012-02-20 04:08:31

2

retief的答案没错。应该注意的是,if是Clojure中的一个表达式,而不仅仅是一个条件构造。因此,它有一个返回值,你可以使用返回值作为参数传递给函数:

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

你可以把它作为在Java中三元运算符。

0

注意,由于Clojure的1.5这个可以写

(cond-> opts (something) (merge {:a b}))