2

我试图在 Clojure 中找出这个 Java 的等价物:

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

    // continue do some computing
    return result;
}

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

4

4 回答 4

5

One of the main guiding principals when programming with Clojure is that everything "returns" a value, though it is usually expressed as "everything evaluates to something". When calling a function the result of the function is the result of the last expression in the function.

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

There are several forms for expressing the idea of "stopping early":

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

or

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

or a simple if expression. The important concept being that everything results in a new value. This has spawned many buzwords in the clojure community including "value oriented programming"

于 2013-08-19T18:21:11.710 回答
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

所以总有一些东西可以回报。

于 2013-08-19T23:59:14.507 回答
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可以在不转换代码的情况下进行中间计算。

于 2013-08-19T18:39:19.183 回答
2

Clojure 没有这样的 return 语句,但是您可以通过在 if 语句上添加一个非常简单的代码分支来获得类似的结果。

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

cond你也可以用或者可能的单子做类似的事情。

于 2013-08-19T16:45:56.393 回答