Clojure中的ClassCastException [英] ClassCastException in Clojure

查看:99
本文介绍了Clojure中的ClassCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Clojure的新手,我一直在尝试其他程序。这是我的程序:

I am new to clojure and i have been trying out different programs. Here is my program :

(defn sdsu-reverse [x]
  (loop [n (count x) x x]
  (if (= 0 n)
    (x)
    (recur (- n 1) (conj (next x) (first x))))))

(= (sdsu-reverse [1 2 3 4 5]) [5 4 3 2 1])

我一直遇到错误:java.lang.ClassCastException:clojure.lang.Cons无法转换为clojure.lang.IFn
C:\Users\Shalima\Documents\Textbooks\函数式编程\程序\sample.clj:44 user / sdsu-reverse

I have been getting error : java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn C:\Users\Shalima\Documents\Textbooks\Functional Programming\Programs\sample.clj:44 user/sdsu-reverse

但是我似乎无法弄清楚。

But I cant seem to figure it out. Could you please help me with this ?

谢谢。

推荐答案

如上述Alex所述,您需要在if表达式中将(x)替换为 x 。在括号中将x括起来会在您想返回值时将其视为函数。

As Alex notes above, you need to replace (x) with x in your if expression. Wrapping x in parentheses treats it as a function when instead you want to return a value.

对于代码中的其他问题:

As for the other issue in your code:

conj 是一个有点混乱的功能。

conj is a slightly confusing function.

clojure.core/cons
([x seq])
  Returns a new seq where x is the first element and seq is
    the rest.

声音足够清晰。但是,看看将 conj 应用于列表而不是向量()。

Sounds clear enough. But look at what happens when conj is applied to a list versus a vector (source).

user=> (conj [1 2 3] 4)
[1 2 3 4]

user=> (conj '(1 2 3) 4)
(4 1 2 3)

原因与向量和列表数据类型的构造方式有关。向量从右侧接收新值;列表,从左侧开始。

The reason for this has to do with how the vector and list datatypes are constructed. Vectors receive new values from the righthand side; lists, from the lefthand side.

当您呼叫 conj(next x)(first x)时,您实际上是在呼叫 conj'(2 3 4)'(1),一遍又一遍。因此,您最终获得了与开始时相同的值。

When you call conj (next x) (first x), you effectively are calling conj '(2 3 4) '(1), over and over again. So you end up with the same value that you started at.

更好的方法是按以下方式使用递归。

A better approach would be to use recursion as follows.

(defn sdsu-reverse [x]
  (if (empty? x)
    nil
    (cons (last x) (sdsu-reverse (drop-last x)))))

我希望这会有所帮助。

编辑,以回应Leonid的评论。

Edit in response to Leonid's comments.

莱昂尼德(Leonid)是正确的,即上述方法对于大序列将失败。或者,您可以执行以下操作:

Leonid is correct that the above will fail for large sequences. Alternatively you could do something like

(defn reverse' 
  ([x] (reverse' x nil))
  ([x acc] (if (empty? x) 
             acc 
             (recur (rest x) (cons (first x) acc)))))

这篇关于Clojure中的ClassCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆