在Clojure中創建Java類有幾種不同的方式,那麼Clojure中的gen-class
,proxy
和reify
之間的選擇有什麼折衷? (有沒有其他方法可以創建我沒有列出的Java類?)在Clojure中創建Java類的選項
我的基本理解是我已經按照權力的降序列出了這些構造。
在Clojure中創建Java類有幾種不同的方式,那麼Clojure中的gen-class
,proxy
和reify
之間的選擇有什麼折衷? (有沒有其他方法可以創建我沒有列出的Java類?)在Clojure中創建Java類的選項
我的基本理解是我已經按照權力的降序列出了這些構造。
使用gen-class
當你想要一個命名的類,或者你想添加新的方法到你創建的對象。 gen-class
依賴於AOT編譯。
當你想要一個匿名的,一次性實現你使用的類型reify
或proxy
。他們不依賴AOT編譯。以下是它們的區別:
reify
只支持協議或接口,proxy
也支持具體的超類。reify
使用真正的類方法,proxy
使用外部函數。reify
使用直接方法查找,而proxy
使用映射進行方法查找。reify
不支持動態交換方法,但proxy
的確如此。reify
將執行比proxy
好,所以你應該總是使用reify
時,應儘可能。當reify
的限制過於禁止時,僅使用proxy
。
除了gen-class,proxy和reify,我們還有defrecord和deftype。後面這兩個選項應該是您創建命名java類的第一選擇(在defrecord的情況下,您是任何具有命名組件的結構的首選)。
datatypes page on clojure.org是關於此主題的很好參考。 defrecord,deftype和reify比1.2版本中引入的gen-class和proxy更新(我認爲 - 可能是1.1)。 Defrecord和deftype都創建符合接口的類,但不允許繼承。如果你需要繼承,gen-class(和匿名類代理)仍然是你唯一的選擇。
Defrecord和deftype的區別在於你免費贈送的東西。 Defrecord自動創建一個符合IPersistentMap和ISeq的類。另一方面,Deftype可以讓你更好地控制你的課程,甚至允許可變字段(不允許在defrecord中)。一般來說,deftype用於數據結構的低級實現,而defrecord則用於大多數日常使用。