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

欢迎!请参阅关于页面以了解更多关于如何使用本站的信息。

0
编译器

举例说明:clojure/tools.logging。

重现步骤
- 静态编译 clojure/tools.logging (clojure.tools.logging 和 clojure.tools.logging.impl) 中所有的命名空间。
- 将结果放在类路径上,然后静态编译 clojure/java.data (clojure.java.data)。
- 在第二次编译的输出中观察 clojure/tools/logging$eval32$fn__33.class(确保为两次编译使用不同的输出目录)。

这通常是无害的,但如果尝试缓存静态编译输出,则可能成为问题。当以这种方式尝试缓存之前的静态编译运行时,有时会导致两个无关的命名空间生成相同的文件名。如果它们具有相同的内部表示,那就没问题,但无法保证它们具有相同的内部表示(因为 32 和 33 都是 (gensym))。这取决于类路径中哪个占上风,可能会导致严重问题。

我不是这方面的专家,但最好这些“额外”文件是作为 tools.logging 的一部分生成,或者以某种方式别名到它们编译的命名空间中(例如 clojure/java/data/$clojure$tools$logging$eval32$fn__33.class 或 clojure/tools/logging/$clojure$java$data$eval32$fn_33.class)。

2 答案

0

评论者:hiredman

clojure/tools.logging 使用 eval 来在类路径上存在某些类时生成一些代码,eval 生成类文件,当您开启静态编译时,这些类文件将被输出到文件系统。

类文件名之所以是这个样子,是因为 eval 发生在 tools.logging 命名空间加载时,因此 ns 变量的值是 tools.logging 命名空间,这是编译器生成名称的来源。

0
参考: https://clojure.atlassian.net/browse/CLJ-1916(由alex+import报告)
...