【问题标题】:ClassCastException java.lang.Boolean cannot be cast to clojure.lang.IFnClassCastException java.lang.Boolean 不能转换为 clojure.lang.IFn
【发布时间】:2013-01-28 09:33:48
【问题描述】:
(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)

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

    你得到了双括号中的 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 的 truthiness,它可以在条件句中以与 true 和 false 大致相同的方式使用。

    【讨论】:

      【解决方案2】:

      正如我所发现的,即使 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))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2017-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多