2024 Clojure 状态调查 中分享您的想法!

欢迎!请访问 关于 页面了解更多有关如何使用的详细信息。

0
错误
已关闭

问题说明

clojure.core/deref 函数被一个不是 clojure.lang.IDerefjava.util.concurrent.Future 的实例调用时,会抛出难以理解的 ClassCastException。在我的经验中,在引导新 Clojure 用户(在我的工作和开源项目中),这经常出现,因为它并不指向代码中的任何明显地方。即使有堆栈跟踪,它也只指向 deref-future 的定义(而不是函数体内的具体行),这进一步导致了混淆。

讨论

在 Slack 上,我提出了将 deref 的实现改为类似以下内容:(cond (instance? clojure.lang.IDeref ref) ... (instance? java.util.concurrent.Future ref) ... :else (throw (IllegalArgumentException (str ref " cannot be deref'd as it is of type " (class ref) ".")))

Sean Corfield 提到,这种修正会降低所有非-IDeref 使用 deref 的性能,我承认但认为这是可以接受的。

重复

user=> (def a {})
#'user/a

user=> @a
Execution error (ClassCastException) at user/eval22861 (REPL:0).
class clojure.lang.PersistentArrayMap cannot be cast to class java.util.concurrent.Future (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.util.concurrent.Future is in module java.base of loader 'bootstrap')

user=> (pst)
ClassCastException class clojure.lang.PersistentArrayMap cannot be cast to class java.util.concurrent.Future (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.util.concurrent.Future is in module java.base of loader 'bootstrap')
    clojure.core/deref-future (core.clj:2315)
    clojure.core/deref-future (core.clj:2315)
    clojure.core/deref (core.clj:2338)
    clojure.core/deref (core.clj:2323)
    user/eval22863 (NO_SOURCE_FILE:0)
    user/eval22863 (NO_SOURCE_FILE:-1)
    clojure.lang.Compiler.eval (Compiler.java:7194)
    clojure.lang.Compiler.eval (Compiler.java:7149)
    clojure.core/eval (core.clj:3215)
    clojure.core/eval (core.clj:3211)
    clojure.main/repl/read-eval-print--9206/fn--9209 (main.clj:437)
    clojure.main/repl/read-eval-print--9206 (main.clj:437)
已关闭,作为: 在非-IDeref 上调用 deref 的错误信息无帮助 的重复问题
看起来这是 https://ask.clojure.org/index.php/1553/error-message-when-calling-deref-on-non-ideref-is-unhelpful 中的重复问题,不幸的是,我在发布后才找到了它。
by
谢谢,我在ask和jira上都没有找到,会把这个问题标签转移到那个话题上。
...