12
(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 用户/是成员?(NO_SOURCE_FILE:28)

为什么?我知道,如果一个表达式用括号括起来,那么这意味着它将被评估为一个函数..

4

2 回答 2

18

你得到了双括号中的 cond 表达式。这会导致 cond 的最终结果(真或假)被作为函数调用。修复它,它可以工作。

=> (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 的真实性,它可以在条件句中以与 true 和 false 大致相同的方式使用。

于 2013-01-28T09:49:30.503 回答
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))))
于 2021-06-10T18:49:47.623 回答