【问题标题】:Clojure multimethod dispatch by java genericsjava泛型的Clojure多方法调度
【发布时间】:2017-08-24 14:19:18
【问题描述】:

我需要的可能解决方案:

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

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

我的问题的完整解释

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

我在 Clojure 中使用一个 java 库。一些函数返回我想要转换为 clojure 映射的 java 类。我正在使用java.data 库进行此操作。

在大多数情况下,这可以正常工作。出于某种原因,我需要为几个类实现 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)))

但我遇到了一些由于某种原因无法“映射”的类。

(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() 的返回值类型是Map&lt;Currency,Balance&gt;,看起来 java.data 不知道如何处理地图。

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

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

以防万一,Java 库是 XChange。 Wallet 类的问题。方法 getBalances()。

【问题讨论】:

  • 泛型类型信息在 Java(或 Clojure)中在运行时不可用,原因是一个称为“类型擦除”的过程(在编译期间剥离泛型类型信息)。也许使用clojure.walkbean 手动进行转换并自定义处理:balances 条目?

标签: java generics clojure dispatch multimethod


【解决方案1】:

如 cmets 中所述,在运行时使用“泛型类型”可能是行不通的。但是,it appears java.data 库不会在 Map 实例中的键和值上递归调用 from-javafrom-java 对于Map 的默认实现就是(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))))

【讨论】:

  • Suure.. 我尝试实现 IPersistentMap,但没有猜到 java.util.Map。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多