我在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)
然后编译器抛出: ClassCastException MyProject.core.TestType无法强制转换为MyProject.core.TestType 。我做错了什么,或者这是一个错误?请注意,如果我从test-function中删除类型注释,那么它只是:
(defn test-function [a-testtype]
(print (.geta a-testtype)))
然后代码工作正常,但我得到一个关于反射的警告(启用了反射警告),并且它运行得更慢,这违背了在我当前用例中使用deftype的目的。
编辑:好的,代码在repl中工作,但是当我使用ctrl-alt-s加载它时(我在Eclipse中通过逆时针运行它)。所以问题似乎是Eclipse或逆时针。
答案 0 :(得分:5)
当您重新定义类型(使用deftype
或defrecord
)时会发生这种情况,但在某处,使用以前存在的类,在您的情况下使用类型提示。
我无法使用CountercClockwise的 Ctrl Alt S 重现您描述的行为,但它确实会以新鲜的方式评估以下表达式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)