gpt4 book ai didi

java - Clojure reify - 使用另一个宏自动实现 Java 接口(interface)?

转载 作者:行者123 更新时间:2023-12-02 00:56:37 27 4
gpt4 key购买 nike

我有一个仅发出事件的 java 接口(interface),我正在尝试在 Clojure 中实现它。 Java接口(interface)是这样的(现实中还有很多其他方法):

public interface EWrapper {

void accountSummary(int reqId, String account, String tag, String value, String currency);
void accountSummaryEnd(int reqId);
}

我的 Clojure 代码如下所示:

(defn create
"Creates a wrapper calling a single function (cb) with maps that all have a :type to indicate
what type of messages was received, and event parameters
"
[cb]
(reify
EWrapper

(accountSummary [this reqId account tag value currency]
(dispatch-message cb {:type :account-summary :request-id reqId :account account :tag tag :value value :currency currency}))

(accountSummaryEnd [this reqId]
(dispatch-message cb {:type :account-summary-end :request-id reqId}))

))

我有大约 75 个函数要“实现”,我的所有实现所做的就是调度一个看起来像 {:type waiting-function-name-kebab-case :parameter-one-kebab-caseparameter-one- 的映射value :parameter-two-kebab-caseparameter-two-value} 等。对于另一个宏来说似乎已经成熟了 - 这也会更安全,因为底层接口(interface)会更新更多功能,我的实现也会如此。

这可能吗?我该如何开始呢?我的理想情况是直接读取 .java 代码,但我也可以手动将 Java 代码粘贴到映射结构中?谢谢,

最佳答案

你可以自己解析出简单的方法数据(我自己没有尝试过反射API)。这是一个示例,包括要演示的单元测试。

首先,将 Java 源代码放入 Clojure 数据结构中:

(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[camel-snake-kebab.core :as csk]
[schema.core :as s]
[tupelo.string :as ts]))

(def java-spec
(quote {:interface EWrapper
:methods [; assume have structure of
; <ret-type> <method-name> <arglist>, where <arglist> => (<type1> <name1>, <type2> <name2> ...)
void accountSummary (int reqId, String accountName, String tag, String value, String currencyName)
void accountSummaryEnd (int reqId)
]
}))

然后,一个函数将方法规范分开,并将参数解构为类型和名称。我们使用一个库将 CamelCase 转换为 kabob-case:

(defn reify-gen
[spec-map]
(let [methods-data (partition 3 (grab :methods spec-map))
; >> (spyx-pretty methods-data)
method-entries (forv [mdata methods-data]
(let [[ret-type mname arglist] mdata ; ret-type unused
mname-kebab (csk/->kebab-case mname)
arg-pairs (partition 2 arglist)
arg-types (mapv first arg-pairs) ; unused
arg-names (mapv second arg-pairs)
arg-names-kebab (mapv csk/->kebab-case arg-names)
arg-names-kebab-kw (mapv ->kw arg-names-kebab)
mresult (list mname (prepend
(quote this)
arg-names)
(list
mname-kebab
(glue {:type (->kw mname-kebab)}
(zipmap arg-names-kebab-kw arg-names))))]
; (spyx-pretty mresult)
mresult ))]
(->list
(prepend
(quote reify)
(grab :interface spec-map)
method-entries))))

以及一个单元测试来演示:

(dotest
(newline)
(is= (spyx-pretty (reify-gen java-spec))
(quote
(reify
EWrapper
(accountSummary
[this reqId accountName tag value currencyName]
(account-summary
{:type :account-summary
:req-id reqId,
:account-name accountName,
:tag tag,
:value value,
:currency-name currencyName}))
(accountSummaryEnd
[this reqId]
(account-summary-end {:type :account-summary-end, :req-id reqId})))

))
)

关于java - Clojure reify - 使用另一个宏自动实现 Java 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61281406/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com