ClassCastException MyType不能被转换为MyType?

时间:2022-06-01 19:29:32

I have encountered a problem when using deftype in Clojure. If I run the following code:

在Clojure中使用deftype时遇到了一个问题。如果我运行以下代码:

(defprotocol TestProt
  (geta [this])
  (getb [this]))

(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

(defn test-function [^TestType a-testtype]
  (print (.geta a-testtype))) 

(def test-tt (TestType. 1 1))

(test-function test-tt)

Then the compiler throws: ClassCastException MyProject.core.TestType cannot be cast to MyProject.core.TestType. Am I doing something wrong, or is this a bug? Note that if I remove the type annotation from test-function, so it's just:

然后编译器抛出:ClassCastException MyProject.core。不能将TestType转换为MyProject.core.TestType。是我做错了什么,还是这个bug?注意,如果我从测试函数中删除类型注释,那么它就是:

(defn test-function [a-testtype]
  (print (.geta a-testtype))) 

Then the code works fine, but I get a warning (with warn-on-reflect enabled) about reflection, and it runs slower, which defeats the purpose of using deftype in my current use-case.

然后代码正常工作,但是我得到了一个关于反射的警告(带有警告的支持),并且它运行得更慢,这违背了在我当前的用例中使用deftype的目的。

Edit: Okay, the code works in the repl, but not when I load it using ctrl-alt-s (I'm running it in Eclipse via Counterclockwise). So the problem seems to be with Eclipse or Counterclockwise.

编辑:好的,代码在repl中工作,但是当我使用ctrl-alt-s加载它时(我用逆时针的方式在Eclipse中运行它)。因此,问题似乎是与Eclipse或逆时针的。

1 个解决方案

#1


5  

This kind of thing happens when you redefine a type (with deftype or defrecord) but somewhere there's a use of the previously existing class hanging around, in your case in the type hint.

当您重新定义一个类型(有deftype或defrecord)时,这种事情就会发生,但是在某个地方有一个使用以前存在的类,在您的例子中,在类型提示中。

I couldn't reproduce the behavior you describe with CountercClockwise's CtrlAltS, but it does appear evaluating the following expressions in a fresh REPL, so it might somehow help to diagnose your specific situation.

我无法复制您用反cclockwise的ctrl - alts来描述的行为,但是它确实在一个新的REPL中对下列表达式进行了评估,因此它可能有助于诊断您的特定情况。

(defprotocol TestProt
  (geta [this])
  (getb [this]))

(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

(defn test-function [^TestType a-testtype]
  (print (.geta a-testtype)))

(def test-tt (TestType. 1 1))

(println :first (test-function test-tt))

;= :first 1

;; redefine the type...
(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

;; ...and the test-tt var with the new version     
(def test-tt (TestType. 1 1))

(println :second (test-function test-tt))

;= ClassCastException user.TestType cannot be cast to user.TestType  user/test-function (NO_SOURCE_FILE:89) 

#1


5  

This kind of thing happens when you redefine a type (with deftype or defrecord) but somewhere there's a use of the previously existing class hanging around, in your case in the type hint.

当您重新定义一个类型(有deftype或defrecord)时,这种事情就会发生,但是在某个地方有一个使用以前存在的类,在您的例子中,在类型提示中。

I couldn't reproduce the behavior you describe with CountercClockwise's CtrlAltS, but it does appear evaluating the following expressions in a fresh REPL, so it might somehow help to diagnose your specific situation.

我无法复制您用反cclockwise的ctrl - alts来描述的行为,但是它确实在一个新的REPL中对下列表达式进行了评估,因此它可能有助于诊断您的特定情况。

(defprotocol TestProt
  (geta [this])
  (getb [this]))

(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

(defn test-function [^TestType a-testtype]
  (print (.geta a-testtype)))

(def test-tt (TestType. 1 1))

(println :first (test-function test-tt))

;= :first 1

;; redefine the type...
(deftype TestType [a b]
  TestProt
  (geta [this] a)
  (getb [this] b))

;; ...and the test-tt var with the new version     
(def test-tt (TestType. 1 1))

(println :second (test-function test-tt))

;= ClassCastException user.TestType cannot be cast to user.TestType  user/test-function (NO_SOURCE_FILE:89)