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

欢迎!请查看关于页面以了解有关该功能的更多信息。

+1点赞
Clojure
(ns graalvm-list-issue.main
  (:require
   [clojure.java.io :as io])
  (:gen-class))

(defn- home-path []
  (System/getProperty "user.home"))

(defn- local-dir []
  (io/file (home-path) ".local"))

(defn -main [& _args]
  (println (seq (.list (io/file (home-path) ".local"))))
  (println (seq (.list (local-dir)))))

(完整代码见此处:https://github.com/conao3/clojure-graalvm-list-issue)

第一个println行没有反射,第二个println行有反射,在GraalVM中执行时发生错误。
我认为这两个调用之间没有区别,且由io/file作为local-dir的返回值显然是,它应该被推断为java.io.File。您怎么看?


研究Clojure源代码

关键函数是hasJavaClassgetJavaClass
https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L359-L361

FnExpr: https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L4450-L4454

InvokeExpr: https://github.com/clojure/clojure/blob/8c8e4f6ef21f3d0f59deb60cdc7e1b584f596d59/src/jvm/clojure/lang/Compiler.java#L4286-L4290

2 个答案

0点赞

local-dir实际上返回了Object,因为Clojure中所有函数在没有返回类型提示时都会这样做。这里没有推断。

您可以对其进行提示,使其返回File(defn- local-dir ^java.io.File [] ..)

这样就不会出现反射。

分析代码,很明显 `io/file` 的返回值是函数的返回值,而且由于 `io/file` 的返回值是 `java.io.File`,我们可以推测该函数本身的返回值也可能是 `java.io.File`。
0点赞

虽然在这个例子中这似乎很明显,但当你引入条件语句/多个尾部位置和原始数据类型时,它会变得更加复杂。对于多个尾部位置,答案实际上是多个答案,可能需要找到一个共同的超类型或在该情况下省略。

此外,因为类型提示主要用于 Java 互操作,因此真正需要返回类型提示的情况相对较小(许多程序可能没有这种情况)。

目前,为了生产有限作用的产物所付出的努力可能不值得,但也许是将来值得关注的事情。

...