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

时间:2013-01-28 09:33:49

标签: clojure

(defn is-member? [a lst] 
((cond 
        (empty? lst) false
        (= a (first lst)) true
        :else (is-member? a (rest lst))
    )))

(is-member? :b '(:a :b :c))

当我执行上面的代码时,我收到错误

  

ClassCastException java.lang.Boolean不能强制转换为clojure.lang.IFn user / is-member? (NO_SOURCE_FILE:28)

为什么呢? 我理解如果表达式括在括号中,那么这意味着它将被评估为函数..

2 个答案:

答案 0 :(得分:15)

你得到了双括号中的cond表达式。这导致cond(true或false)的最终结果被调用为函数。修复它并且它有效。

=> (defn is-member?
     [a lst] 
     (cond 
       (empty? lst) false
       (= a (first lst)) true
       :else (is-member? a (rest lst))))
#'user/is-member?

=> (is-member? :b '(:a :b :c))
true

顺便说一下,在Clojure中最常用的方法是使用some

=> (some #{:b} [:a :b :c])
:b

这会返回实际的第一个值,但由于Clojure的truthiness,它可以在条件语句中以与true和false非常相同的方式使用。

答案 1 :(得分:0)

正如我所发现的,即使 cond 表达式在单括号中,如果将每个条件测试表达式对括在括号中,您也会得到相同的 ClassCastException

;; INCORRECT
(defn is-member?
  [a lst] 
  (cond 
    ((empty? lst) false)
    ((= a (first lst)) true)
    (:else (is-member? a (rest lst)))))

;; CORRECT
(defn is-member?
  [a lst] 
  (cond 
    (empty? lst) false
    (= a (first lst)) true
    :else (is-member? a (rest lst))))