[英]How to use defrecord in Clojure to extend a Java class?
根據我的研究,擴展 Java class 的方法基本上是使用命名空間中的 gen-class 或代理。 但是看Clojure選型流程圖,好像建議我可以用record擴展一個Java class:
使用解凍記錄
所以問題是......如何?
例如(從這個):
public final class Second extends Struct {
public final Signed32 a_number = new Signed32();
public Second(final Runtime runtime) {
super(runtime);
}
}
public final class Top extends Struct {
public final Second second = inner(new Second(getRuntime()));
public final Second[] seconds = array(new Second[5]);
public final Signed32 another_number = new Signed32();
public final Signed32[] more_numbers = array(new Signed32[5]);
public Top(final Runtime runtime) {
super(runtime);
}
}
我...
(defrecord Second)
(extend jnr.ffi.Struct
Second)
?
我認為流程圖是錯誤的。 檢查Clojure - 數據類型:deftype、defrecord 和 reify文檔我們可以看到:
- deftype/defrecord 可以實現一個或多個協議和/或接口
沒有提到擴展現有的 class。事實上,查看defrecord
本身的文檔沒有提到擴展現有的類,除了Object
作為特例。
抱歉, proxy
或gen-class
似乎是您唯一的選擇。
為什么需要命名類型? 如果,如您所說,您不需要從 Java 靜態引用它,我看不出有任何特別的理由來命名該類型。 如果你正確回答了這個問題,它會引導你到proxy
。 您的問題是您選擇了不一致的答案:您說您需要一個已命名的 class,但對於您可能需要一個的任何原因都沒有回答是。 流程圖考慮的原因是 Java 代碼可能希望通過名稱引用您的代碼,在這種情況下gen-class
。 但是,一方面說您必須擴展 Java class,另一方面說您的新類型將是一個簡單的數據載體,為域值建模是沒有意義的。 Clojure 記錄在這方面做得很好,但是擁有一個來自 Java 的令人討厭的可變基礎 class 並不能構成一個好的域 object。
也就是說,如果您對“建模域類型”回答“否”,它會引導您使用deftype
,它也不能擴展 class。我認為它允許您逃離“互操作區”是一個錯誤如果你想擴展一個 class: 最好將接口和子類分開,但流程圖只能這么大。
FWIW 對原始流程圖帖子的評論包括您的問題和作者的回答,回應了我使用proxy
的建議以及流程圖已經足夠大的問題:
第一個決定並不僅僅表明您需要擴展 class — 它包括實現接口。 所以,那里有點模棱兩可。 當然,你在 gen-class-land 那里,但我認為將事情分解更多以消除歧義會使流程圖更大一些。
FWIW,我個人會在那里放棄命名類型要求,使用代理,然后只定義 (class (create-proxy-instance …)) 的結果? 檢查等(假設這就是您需要命名類型的原因)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.