clojure中的递归代码和类强制转换异常

时间:2016-12-19 12:20:53

标签: recursion clojure classcastexception

(defn fib [n]
         (if ((= n 0) 0)
           ((= n 1) 1)
           (:else (+ (fib (- n 1)) 
              (fib (- n 2))))))
(fib 10)

ClassCastException无法将java.lang.Boolean强制转换为clojure.lang.IFn

以下相同的例外情况。

(defn A [x y]
 (cond ((= y 0) 0)
       ((= x 0) (* 2 y))
       ((= y 1) 2)
       (:else (A (- x 1) (A x (- y 1))))))
(A  1 10)

这有什么不妥,无法理解,请解释一下?

1 个答案:

答案 0 :(得分:1)

你太近了!

(defn A [x y]
  (cond (= y 0) 0
        (= x 0) (* 2 y)
        (= y 1) 2
        :else (A (- x 1)
                 (A x (- y 1)))))

你只是有太多的括号包裹着cond表格。

现在正常工作:

user=> (A  1 10)
1024

你的递归fib函数有一些类似的问题。请注意缩进 - 这将始终帮助您了解问题所在。

在这种特殊情况下,此行抛出异常ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFn

((= n 1) 1)

...因为(= n 1)被评估为布尔值true或false,并且因为此结果布尔值位于((= n 1) 1)形式的第一个位置,这意味着Clojure将尝试调用布尔值作为函数(clojure.lang.IFn)。

这就是Clojure真正看到的:

(true 1)

这就是为什么Clojure试图将布尔值转换为IFn的原因。 IFn是一个代表可调用函数的Java接口。

我希望这是有道理的。