[英]How to aot-compile gen-class classes with cyclic type hints?
在Clojure中,我將gen-class
與Java庫一起使用。 程序員通常提供兩個類,分別實現一個接口和擴展一個類。 這兩個類應該相互引用,並且鑒於庫的設計方式,很難避免這種循環依賴性。
周期不是問題-編譯器不必了解它們-除非我試圖通過明智地添加類型提示(以大幅度的加速)來優化代碼。 通過重組代碼,我能夠避免編譯器抱怨循環依賴,並將問題簡化為單個類型提示:
在一個源文件Foo.clj中,我具有此函數/方法,該方法/方法是類實現的接口所必需的:
(defn -step
[^Foo this ^Bar bar]
...)
另一個源文件Bar.clj創建了Foo實例的集合,因此我必須在此引用Foo類。 在我的Leiningen project.clj中,我有這樣一行:
:aot [Foo Bar]
我沒有周期性的依賴錯誤。 相反,我得到ClassNotFoundException
:如果我將Foo
放在:aot
,則編譯器會抱怨它在編譯Foo
時不了解Bar
,因為^Bar
類型提示在-step
。 如果我將Bar
放在:aot
,則編譯器在編譯Bar
時找不到Foo
,這是因為Bar.clj中對(Foo.)
的調用。
我當前的解決方案是這樣的:
^Bar
類型暗示的定義-step
在Foo.clj。 -step
在Foo.clj。 Foo
(即再次運行“ lein compile”)。 之所以可行,是因為第二次編譯Foo
時, Bar
存在,因此編譯器不會抱怨。
有沒有一種方法可以編譯兩個類而又不刪除並重新添加類型提示? (或者我應該考慮這種情況的另一種方式?)
我的傾向是在foo名稱空間中為Foo添加一個工廠函數。
(defn new-foo [] (Foo.)) ; parameterize to your satisfaction
然后,您可以在以下答案中使用前向聲明技術來從Bar中訪問new-foo-從Clojure中的另一個命名空間中前向聲明var?
當然,這仍然很棘手-如果還有其他方法可以打破依賴關系循環,則可以采取這種方法。 如果可以的話,如何在同一個命名空間中定義Foo和Bar? 它們看起來確實緊密耦合,盡管很難用抽象的問題描述來說明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.