在 Clojure 中,我使用gen-class
的是 Java 库。程序员通常提供两个类,分别实现一个接口和扩展一个类。这两个类应该相互引用,考虑到库的设计方式,很难避免这种循环依赖。
循环不会是一个问题——编译器不必知道它们——除了我试图通过明智地添加类型提示来优化代码(具有巨大的加速)。通过重新组织代码,我已经能够避免编译器对循环依赖的抱怨,并且我已经将问题简化为单一类型提示:
在一个源文件 Foo.clj 中,我有这个函数/方法,这是该类实现的接口所必需的:
(defn -step
[^Foo this ^Bar bar]
...)
另一个源文件 Bar.clj 创建了 Foo 实例的集合,因此我必须在其中引用 Foo 类。在我的 Leiningen project.clj 中,我有这样一行:
:aot [Foo Bar]
我没有收到循环依赖错误。相反,我得到一个ClassNotFoundException
: 如果我把Foo
first 放在后面:aot
,编译器会抱怨它不知道什么Bar
时候编译Foo
,^Bar
因为-step
. 如果我Bar
先放在后面,编译器在编译时:aot
找不到,因为在 Bar.clj 中的调用。Foo
Bar
(Foo.)
我目前的解决方案是这样的:
- 删除Foo.clj
^Bar
中定义的类型提示。-step
- 编译这两个类。
-step
在 Foo.clj 中重新添加类型提示。- 编译
Foo
(即再次运行“lein compile”)。
这是有效Foo
的,因为第二次编译时Bar
存在,所以编译器不会抱怨。
有没有办法在不删除和添加类型提示的情况下编译这两个类?(或者我应该以不同的方式思考这种情况?)