gpt4 book ai didi

java - 如何使用循环类型提示来编译 gen-class 类?

转载 作者:行者123 更新时间:2023-11-30 08:12:05 25 4
gpt4 key购买 nike

在 Clojure 中,我将 gen-class 与 Java 库一起使用。程序员通常提供两个类,分别实现接口(interface)和扩展类。这两个类应该互相引用,并且考虑到库​​的设计方式,很难避免这种循环依赖。

循环不会成为问题——编译器不必知道它们——除了我试图通过明智地添加类型提示(具有巨大的加速)来优化代码。我已经能够通过重新组织代码来避免编译器对循环依赖项的提示,并且我已将问题简化为单一类型提示:

在一个源文件 Foo.clj 中,我有一个函数/方法,该类实现的接口(interface)需要它:

(defn -step
[^Foo this ^Bar bar]
...)

另一个源文件 Bar.clj 创建了 Foo 实例的集合,因此我必须在那里引用 Foo 类。在我的 Leiningen project.clj 中,我有这样一行:

:aot [Foo Bar]

我没有收到循环依赖错误。相反,我得到了 ClassNotFoundException:如果我将 Foo 放在 :aot 之后,编译器会提示它不知道 Bar 当它编译 Foo 时,因为 -step 中的 ^Bar 类型提示。如果我把 Bar 放在 :aot 之后,编译器在编译 Bar 时找不到 Foo,因为对 Bar.clj 中 (Foo.) 的调用。

我当前的解决方案是这样的:

  1. 删除 Foo.clj 中 -step 定义中的 ^Bar 类型提示。
  2. 编译这两个类。
  3. 将类型提示添加回 Foo.clj 的 -step 中。
  4. 编译Foo(即再次运行“leincompile”)。

这是有效的,因为当第二次编译 Foo 时,Bar 存在,因此编译器不会提示。

有没有一种方法可以编译这两个类而不删除并添加回类型提示? (或者我应该以不同的方式思考这种情况?)

最佳答案

我倾向于在 foo 命名空间中为 Foo 添加一个工厂函数。

(defn new-foo [] (Foo.)) ; parameterize to your satisfaction

然后您可以在以下答案中使用前向声明技术从 Bar - Forward-declaring a var from another namespace in Clojure? 访问 new-foo

这当然仍然令人讨厌 - 如果有任何其他方法可以打破依赖循环,您可能会采取它。如果有意义的话,在同一个命名空间中定义 Foo 和 Bar 怎么样?它们看起来确实非常紧密地耦合,尽管通过抽象的问题描述很难区分。

关于java - 如何使用循环类型提示来编译 gen-class 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30251692/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com