clojure - 使用宏动态生成 reify 子句
问题描述
我正在尝试包装一个实现并为包装对象实现的所有接口动态生成 reify 子句。
例如:
我想生成:
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped)))
或者
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped))
AnotherInterface
(bar [_] (.bar wrapped)))
取决于是wrapped
只实现BaseInterface
还是两者兼而有之BaseInterface
和AnotherInterface
。
我尝试了类似以下的方法,但它失败了,因为宏在编译时被评估并且我的第二个参数(cond->
表达式)没有它的运行时值:
(defmacro add-interface-implementations
"Adds additional interface implementations to a reify expression.
This is useful to create a reify expression dynamically without introducing if-else branching."
[reify-expr interface->methods]
(reduce
(fn [expr# entry#]
(println "expr#" expr#)
(println "entry#" entry#)
(let [[interface# body#] entry#]
(cons
(first expr#)
(cons interface#
(reduce
(fn [e# m#]
(cons m# e#))
(rest expr#)
body#)))))
reify-expr
interface->methods))
(add-interface-implementations
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped)))
(cond-> {}
(instance? AnotherInterface foo)
(assoc AnotherInterface [(bar [_] (.bar wrapped))])))
关于如何实现我正在尝试的任何建议。我想避免 if-else 分支,因为一旦我有更多接口,它就会导致组合爆炸。
解决方案
推荐阅读
- javascript - 营业时间内的聊天按钮显示
- python - Coordinate descent in Python
- r - X2 独立性测试
- ios - 斯威夫特:为什么本地化有时需要添加观察者才能使其工作,但有时却不需要
- reactjs - 嵌套地图不会在本机反应中呈现 jsx
- snakemake - 通过snakemake中的规则限制工作数量
- r - ggplot2:跨多个绘图的统一色标
- powershell - 如何将图像放入从命令行生成的 Lotus Notes 电子邮件中?
- vba - VBA,在列(C)中查找最大值并返回其值和相邻单元格的值
- javascript - 如何在反应中使用gapi