2015-09-25 78 views
3

我試圖用gen-class覆蓋clojure中的compare(WriteableComparable a, WriteableComparable b)方法this class。併發症源於一個事實,即這種方法被重載3次:Clojure gen-class用於重載和重寫的方法

  • int compare(WritableComparable a, WritableComparable b)
  • int compare(Object a, Object b)
  • int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2)

到目前爲止,我的嘗試是這樣的:

(gen-class 
:name comparators.MyWriteableComparator 
:extends org.apache.hadoop.io.WritableComparator 
:exposes-methods {compare superCompare} 
:prefix "interop-") 

(defn interop-compare 
    ([this a b c d e f] 
    (.superCompare this a b c d e f)) 
    ([this ^WritableComparable w1 ^WritableComparable w2]   
    (.compareTo (.getSymbol ^SymbolPair w1) 
       (.getSymbol ^SymbolPair w2)))) 

一切都在編譯,但是當我運行它時,我得到一個空poi但我懷疑這是因爲我忽略了錯誤的方法(即代替compare(WritableComparable a, WritableComparable b)而代替compare(Object a, Object b))。 For reference,Object版本的compare呼叫到WriteableComparable版本。我們至少把它縮小到這個clojure代碼(當我用相應的Java版本運行它時,情況很好),這完全有可能是NPE來自其他東西。

是否有方法來指定應該使用哪種重載版本的方法?

(我嘗試添加一個:methods條款列入gen-class電話,但我知道,一個人應該只聲明新的方法,而不是超類的方法。)

回答

5

存在與gen-class工作,並允許壓倒一切的相同參數數量超載的機制方法。除了前綴和方法名稱之外,我們可以使用包含參數類型的名稱來定義變量/函數。要覆蓋像foo(String s, Object o)這樣的方法,我們可以定義一個名爲-foo-String-Object的變量。該代碼將在返回到-foo之前查找因此命名的變量。這至少在one of the Clojure mailing list threads中有記錄。

在實踐中,這意味着你可以編寫如下代碼:

(defn interop-compare [this a b c d e f] 
    (do-array-compare)) 

(defn interop-compare-Object-Object [this a b] 
    (do-object-compare)) 

(defn interop-compare-WritableComparable-WritableComparable [this a b] 
    (do-writable-comparable-thing)) 
+0

哇。另一種使用'gen-class'的方法是黑暗藝術。我曾想過這個問題,但並不需要答案,所以把它放在我的腦海裏。 – Mars