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

欢迎!请查看关于页面以了解更多关于如何使用的信息。

+16
Clojure
编辑

从JDK19+开始,以下内容无需添加类型提示即可成为反射性

(def x 10)
(Thread/sleep x)

有趣的是,在较早的JDK中,上述内容不具备反射性,但当你升级JDK时,反射就开始了。

如果使用native-image,你的程序可能会由于缺少反射配置而失败。

如果有一个接受数字的内置sleep函数将很好,这样我们就不会忘记添加类型提示,并且它会在JDK之间保持一致性。

例如。

(ns clojure.java.misc)
(defn sleep [x]
  (if (number? x)
    (Thread/sleep (long x))
    ....)

将clojure.java.misc的更好名称是welcome。也许只需将其命名为clojure.java或者将其函数放到clojure.core中?

奇怪的是,我现在在1.11.1和JDK 20上根本无法重现它 - 在REPL中,通过执行脚本,通过执行-a-主函数,给变量和函数加额外的包装。
(~/clojure)-(!2001)-> clj
    Clojure 1.12.0-alpha4
    user=> (System/getProperty "java.version")
    "20.0.1"
    user=> (set! *warn-on-reflection* true)
    true
    user=> (def x 1000)
    #'user/x
    user=> (Thread/sleep x)
    反射警告,NO_SOURCE_PATH:1:1 - 无法解析java.lang.Thread的静态方法sleep的调用(参数类型:未知)。
    nil
    user=>
在这种情况下,“正常”的情况应该是调用将正常继续进行,但通过反射来修正(如果你关心的话),可以使用^long类型提示进行修正。然而,在Reflector中存在一个细微的bug,它从不匹配更小的boxed numeric参数作为传递给接收较宽原始参数的方法的有效参数。

在此,如果您在运行时传递boxed Integer,它将不会与Thread.sleep()匹配任何方法。还有一个有用的信息是,当Cheshire读取JSON如果值在整数范围内时,Cheshire将发出boxed Integer对象(有关此事在Cheshire中有一个工单)。

结合这些情况,我们观察到的结果是,如果使用Cheshire(或具有类似行为的其他读取配置文件作为Integer的东西),并且升级到较新的Java,则结果可能不是废弃,而是在运行时出现反射错误。这似乎是不可接受的,因此我们在Clojure 1.11.3和1.12.0-alpha10中提交了https://clojure.atlassian.net/browse/CLJ-2843并修复了此问题。

1 答案

+1 投票
core.async中存在与Thread/sleep的便携式类似物。
by
尽管只需休眠,但引入整个 core.async 似乎过于冗余。
...