如果在Clojure中休息

时间:2013-08-19 16:38:33

标签: clojure

我试图在Clojure中弄清楚这个Java的等价物:

public int compute(int x) {
    if (x < 0) return 0;    

    // continue do some computing
    return result;
}

是否有惯用的Clojure在函数中“中断”处理并返回结果?

4 个答案:

答案 0 :(得分:5)

使用Clojure进行编程时,其中一个主要的指导原则是,所有东西都“返回”一个值,尽管它通常表示为“一切都评估为某种东西”。调用函数时,函数的结果是函数中最后一个表达式的结果

user> (defn foo [] 1 2 3 4)  
#'user/foo 
user> (foo)
4

有几种形式表达“早退”的想法:

user> (defn compute [x] (cond (< x 0) 0  :default (* x 42))) 
#'user/compute
user> (compute 1) 
42

user> (defn compute [x] (if-let [y (< x 0)] (* 8 y) (* 4 x))) 
#'user/compute
user> (compute 1) 
4

或简单的if表达式。重要的概念是一切都会带来新的价值。这在clojure社区中产生了许多口号,包括“价值导向编程”

答案 1 :(得分:3)

没有。没有短路return声明(或breakgoto ...)。回归是隐含的。

在你的例子中,与Clojure相近的是

(defn test [x]
    (if (< x 0)
        0
        (let [result (comment compute result)]
            result)))

但你可能会在没有命名的情况下返回result

(defn test [x]
    (if (< x 0)
        0
        (comment compute result)))

这些运行,但comment始终评估为nil

顺便说一下,如果测试失败,带有两个表达式(而不是完整三个)的if构造会返回nil

(if (< 3 0) 0) ; nil

所以总会有回归的东西。

答案 2 :(得分:2)

Clojure没有这样的return语句,但是你可以通过在if语句上使用一个非常简单的代码分支来实现类似的结果。

(defn compute [x]
    (if (< x 0) 0
       (do ...
           result)))

您也可以使用cond或monad来做类似的事情。

答案 3 :(得分:2)

你真的需要指定:

// continue do some computing

一个例子..

public int test(int x) {
    if (x < 0) 
       return 0;    

    int tmp = getSomthing1(x);
    int tmp2 = getSomething2(x, tmp);
    int result = tmp/tmp2;
    return result;
}

这就像是:

(defn test [x]
    (if (< x 0)
        0  
        (let [tmp (getSomthing1 x)
              tmp2 (getSomething2 x tmp)]
           (/ tmp tmp2))))

您所拥有的是(if predicate consequent alternative),而let可以保留中间计算而无需强制执行代码。