java 泛型的 Clojure 多方法调度

Clojure multimethod dispatch by java generics

我需要的可能解决方案:

如何为 Map<javaType, javaType> 类型的集合实现多方法?像这样:

(defmethod multimethod Map<javaType,javaType> [map]
  {(.key (first map)) (.value (first map))}) 

我的问题的完整解释

也许上面的问题不是我需要解决的问题(只是我认为用泛型实现可以解决我的问题),所以我想我需要提供完整的解释我的问题是什么,并询问社区我需要做什么。

我在 Clojure 中使用 java 库。我想将某些函数 return me java class 转换为 clojure 映射。我正在使用 java.data 库进行此操作。

在大多数情况下,这都可以正常工作。出于某种原因,我需要为多个 classes:

实现 java.data 多方法
;; From java.data readme
(defmethod from-java YourJavaClass [instance]
  ; your custom logic for turing this instance into a clojure data structure)

但没关系,这很好用:

(defmethod jd/from-java CurrencyPair [instance]
  (help/convert-market-keyword (.toString instance)))

但是我遇到了一些class因为某些原因不能"mapped"的

(defmethod jd/from-java AccountInfo [instance]
  {:myWallet (jd/from-java (.getWallet instance))})

(defmethod jd/from-java Wallet [instance]
  {:myBalances (jd/from-java (.getBalances instance))})

(defmethod jd/from-java Balance [instance]
  "BALANCE!!!!") 

(defmethod jd/from-java Currency [instance]
  ;; e.g. converts Currency instance with field "BTC" to keyword :btc
  (help/convert-currency-keyword (.toString instance)))

映射 AccountInfo 实例后,我希望看到这个:

{:myWallet 
  {:myBalances 
    {:btc "BALANCE!!!!"
     :eth "BALANCE!!!!"
     :usdt "BALANCE!!!!"
     ...}

但是看到这个:

{:myWallet 
  {:myBalances 
    {#object[org.knowm.xchange.currency.Currency 0x4faae851 "BTC"] 
     #object[org.knowm.xchange.dto.account.Balance 0x42942aa9 "Balance [currency=GNT, total=null, available=0E-8, frozen=0E-8, borrowed=0, loaned=0, withdrawing=0, depositing=0]"],

     #object[org.knowm.xchange.currency.Currency 0x299d00e0 "ETH"] 
     #object[org.knowm.xchange.dto.account.Balance 0x23f7cb1d "Balance [currency=LSK, total=null, available=0E-8, frozen=0E-8, borrowed=0, loaned=0, withdrawing=0, depositing=0]"],
     ...}

.getBalances() 的 returning 值类型是 Map<Currency,Balance>,似乎 java.data 不知道如何使用地图。

所以,我的问题(目前)是如何为这种收集实现 java.data 多方法。像这样:

(defmethod jd/from-java Map<Currency,Balance> [instance]
  {:cur "BALANCE!!!!"}) 

以防万一,java 库是 XChange。 Wallet class 的问题。方法 getBalances().

如评论中所述,在运行时使用 "generic types" 可能是行不通的。但是,it appears java.data 库不会对 Map 实例中的键和值递归调用 from-javaMapfrom-java 默认实现只是 (into {} instance)。也许 OP 面临的具体问题可以通过为 java.util.Map 重新定义 from-java 方法来解决。新实现会将 from-java 应用于所有键和值。例如:

(defmethod jd/from-java java.util.Map
  [m]
  (zipmap (map jd/from-java (keys m)) (map jd/from-java (vals m))))